diff --git a/Source/Engine/Core/Math/Quaternion.cs b/Source/Engine/Core/Math/Quaternion.cs
index 86a6e4e2d..b69df3969 100644
--- a/Source/Engine/Core/Math/Quaternion.cs
+++ b/Source/Engine/Core/Math/Quaternion.cs
@@ -1479,6 +1479,47 @@ namespace FlaxEngine
return results;
}
+ ///
+ /// Gets rotacion for normal in relation to transform
+ /// Funcion especially created for aligned with axis aligned faces
+ /// use full with
+ ///
+ /// Example code:
+ ///
+ /// GetRotacionFromNormalExample :
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// position = Hit.Collider.Position;
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// rot = .GetRotacionFromNormal(normal,transform);
+ /// SomeObject.Position = point;
+ /// SomeObject.Orientation = rot;
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// the normal vector
+ /// relative to
+ /// normal as rotacion
+ public static Quaternion GetRotacionFromNormal(Vector3 InNormal, Transform InRefrenceTransform)
+ {
+ Float3 up = InRefrenceTransform.Up;
+ var dot = Vector3.Dot(InNormal, up);
+ if (Mathf.NearEqual(Math.Abs(dot), 1))
+ {
+ up = InRefrenceTransform.Right;
+ }
+ return Quaternion.LookRotation(InNormal, up);
+ }
+
///
/// Adds two quaternions.
///
diff --git a/Source/Engine/Core/Math/Quaternion.h b/Source/Engine/Core/Math/Quaternion.h
index 0790dcbfb..2f2c538a6 100644
--- a/Source/Engine/Core/Math/Quaternion.h
+++ b/Source/Engine/Core/Math/Quaternion.h
@@ -660,6 +660,27 @@ public:
// @param roll The roll of rotation (in radians)
// @param result When the method completes, contains the newly created quaternion
static void RotationYawPitchRoll(float yaw, float pitch, float roll, Quaternion& result);
+
+
+ ///
+ /// Gets rotacion for normal in relation to transform
+ /// Funcion especially created for aligned with axis aligned faces
+ /// use full with
+ ///
+ /// the normal vector
+ /// relative to
+ /// normal as rotacion
+ static Quaternion GetRotacionFromNormal(const Vector3& InNormal, const Transform& InRefrenceTransform)
+ {
+ Float3 up = InRefrenceTransform.GetUp();
+ auto dot = Vector3::Dot(InNormal, up);
+ if (Math::NearEqual(Math::Abs(dot), 1))
+ {
+ up = InRefrenceTransform.GetRight();
+ }
+ return Quaternion::LookRotation(InNormal, up);
+ }
+
};
///
diff --git a/Source/Engine/Core/Math/Transform.cs b/Source/Engine/Core/Math/Transform.cs
index e00265f6d..844625514 100644
--- a/Source/Engine/Core/Math/Transform.cs
+++ b/Source/Engine/Core/Math/Transform.cs
@@ -477,6 +477,187 @@ namespace FlaxEngine
Quaternion.Slerp(ref start.Orientation, ref end.Orientation, amount, out result.Orientation);
Float3.Lerp(ref start.Scale, ref end.Scale, amount, out result.Scale);
}
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ /// Example code:
+ ///
+ /// AlignRotacionToObjectAndSnapToGridExample :
+ /// Offset = 50.0f;
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// SomeObject.Transform = .AlignRotacionToNormalAndSnapToGrid
+ /// (
+ /// point,
+ /// normal,
+ /// Offset,
+ /// transform,
+ /// SomeObject.Scale,
+ /// GridSize
+ /// );
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// return scale
+ /// InRefrenceTransform
+ /// rotated and snaped transform
+ public static Transform AlignRotacionToNormalAndSnapToGrid(Vector3 InPoint, Vector3 InNormal, float InNormalOffset, Transform InRelativeTo, Float3 InReturnScale, Vector3 InGridSize)
+ {
+ Quaternion rot = Quaternion.GetRotacionFromNormal(InNormal, InRelativeTo);
+ return new Transform(Vector3.SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, new Vector3(0, 0, InNormalOffset), rot, InGridSize), rot, InReturnScale);
+ }
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ /// Example code:
+ ///
+ /// AlignRotacionToObjectAndSnapToGridExample :
+ /// Offset = 50.0f;
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// SomeObject.Transform = .AlignRotacionToNormalAndSnapToGrid
+ /// (
+ /// point,
+ /// normal,
+ /// Offset,
+ /// transform,
+ /// GridSize
+ /// );
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// InRefrenceTransform
+ /// rotated and snaped transform with scale
+ public static Transform AlignRotacionToNormalAndSnapToGrid(Vector3 InPoint, Vector3 InNormal, float InNormalOffset, Transform InRelativeTo, Vector3 InGridSize)
+ {
+ Quaternion rot = Quaternion.GetRotacionFromNormal(InNormal, InRelativeTo);
+ return new Transform(Vector3.SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, new Vector3(0, 0, InNormalOffset), rot, InGridSize), rot, Float3.One);
+ }
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ /// Example code:
+ ///
+ /// AlignRotacionToObjectAndSnapToGridExample :
+ /// Offset = new Vector3(0, 0, 50f);
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// SomeObject.Transform = .AlignRotacionToNormalAndSnapToGrid
+ /// (
+ /// point,
+ /// normal,
+ /// Offset,
+ /// transform,
+ /// SomeObject.Scale,
+ /// GridSize
+ /// );
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// return scale
+ /// InRefrenceTransform
+ /// rotated and snaped transform
+ public static Transform AlignRotacionToNormalAndSnapToGrid(Vector3 InPoint, Vector3 InNormal, Vector3 InNormalOffset, Transform InRelativeTo, Float3 InReturnScale, Vector3 InGridSize)
+ {
+ Quaternion rot = Quaternion.GetRotacionFromNormal(InNormal, InRelativeTo);
+ return new Transform(Vector3.SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, InNormalOffset, rot, InGridSize), rot, InReturnScale);
+ }
+
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ /// Example code:
+ ///
+ /// AlignRotacionToObjectAndSnapToGridExample :
+ /// Offset = new Vector3(0, 0, 50f);
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// SomeObject.Transform = .AlignRotacionToNormalAndSnapToGrid
+ /// (
+ /// point,
+ /// normal,
+ /// Offset,
+ /// transform,
+ /// GridSize
+ /// );
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// InRefrenceTransform
+ /// rotated and snaped transform with scale
+ public static Transform AlignRotacionToNormalAndSnapToGrid(Vector3 InPoint, Vector3 InNormal, Vector3 InNormalOffset, Transform InRelativeTo, Vector3 InGridSize)
+ {
+ Quaternion rot = Quaternion.GetRotacionFromNormal(InNormal, InRelativeTo);
+ return new Transform(Vector3.SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, InNormalOffset, rot, InGridSize), rot, Float3.One);
+ }
///
/// Tests for equality between two objects.
diff --git a/Source/Engine/Core/Math/Transform.h b/Source/Engine/Core/Math/Transform.h
index 2c51bfa4a..a54c356db 100644
--- a/Source/Engine/Core/Math/Transform.h
+++ b/Source/Engine/Core/Math/Transform.h
@@ -291,6 +291,77 @@ public:
return result;
}
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// return scale
+ /// InRefrenceTransform
+ /// rotated and snaped transform
+ static Transform AlignRotacionToNormalAndSnapToGrid(const Vector3& InPoint, const Vector3& InNormal, float InNormalOffset, const Transform& InRelativeTo, const Float3& InReturnScale, const Vector3& InGridSize)
+ {
+ Quaternion rot = Quaternion::GetRotacionFromNormal(InNormal, InRelativeTo);
+ return Transform(Vector3::SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, Vector3(0, 0, InNormalOffset), rot, InGridSize), rot, InReturnScale);
+ }
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// InRefrenceTransform
+ /// rotated and snaped transform with scale
+ static Transform AlignRotacionToNormalAndSnapToGrid(const Vector3& InPoint, const Vector3& InNormal, float InNormalOffset, const Transform& InRelativeTo, const Vector3& InGridSize)
+ {
+ Quaternion rot = Quaternion::GetRotacionFromNormal(InNormal, InRelativeTo);
+ return Transform(Vector3::SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, Vector3(0, 0, InNormalOffset), rot, InGridSize), rot, Float3::One);
+ }
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local Z grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// return scale
+ /// InRefrenceTransform
+ /// rotated and snaped transform
+ static Transform AlignRotacionToNormalAndSnapToGrid(const Vector3& InPoint, const Vector3& InNormal, const Vector3& InNormalOffset, const Transform& InRelativeTo,const Float3& InReturnScale,const Vector3& InGridSize)
+ {
+ Quaternion rot = Quaternion::GetRotacionFromNormal(InNormal, InRelativeTo);
+ return Transform(Vector3::SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, InNormalOffset, rot, InGridSize), rot, InReturnScale);
+ }
+ ///
+ /// combines funcions
+ /// ,
+ ///
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The local grid offset to applay after snaping
+ /// Normal vector
+ /// Realative transform
+ /// InRefrenceTransform
+ /// rotated and snaped transform with scale
+ static Transform AlignRotacionToNormalAndSnapToGrid(const Vector3& InPoint,const Vector3& InNormal,const Vector3& InNormalOffset, const Transform& InRelativeTo,const Vector3& InGridSize)
+ {
+ Quaternion rot = Quaternion::GetRotacionFromNormal(InNormal, InRelativeTo);
+ return Transform(Vector3::SnapToRotatedGridWithOffset(InPoint, InRelativeTo.Translation, InNormalOffset, rot, InGridSize), rot, Float3::One);
+ }
+
public:
FORCE_INLINE Transform operator*(const Transform& other) const
{
diff --git a/Source/Engine/Core/Math/Vector3.cs b/Source/Engine/Core/Math/Vector3.cs
index 848a3b532..9cda11544 100644
--- a/Source/Engine/Core/Math/Vector3.cs
+++ b/Source/Engine/Core/Math/Vector3.cs
@@ -1685,6 +1685,80 @@ namespace FlaxEngine
return pos;
}
+ ///
+ /// Snaps the on to rotate grid.
+ /// for world aligned grid snapping use instead
+ /// Example code:
+ ///
+ /// SnapToRotatedGridExample :
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// position = Hit.Collider.Position;
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// //Get rotation from normal relative to collider transform
+ /// rot = .GetRotacionFromNormal(normal,transform);
+ /// point = .SnapToRotatedGrid(point,position,rot,GridSize);
+ /// SomeObject.Position = point;
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The center point.
+ /// The rotation of the grid.
+ /// The size of the grid.
+ /// The position snapped to the grid.
+ public static Vector3 SnapToRotatedGrid(Vector3 InPoint, Vector3 InCenterPoint, Quaternion InOrientation, Vector3 InGridSize)
+ {
+ Vector3 p = (InPoint - InCenterPoint) * InOrientation.Conjugated();
+ return (SnapToGrid(p, InGridSize) * InOrientation) + InCenterPoint;
+ }
+ ///
+ /// The same as but with local offset applied after point is spapend
+ /// Example code:
+ ///
+ /// SnapToRotatedGridWithOffsetExample :
+ /// Offset = new Vector3(0, 0, 50f);
+ /// GridSize = * 20.0f;
+ /// RayOrgin;
+ /// SomeObject;
+ ///
+ /// {
+ /// (.RayCast(RayOrgin.Position, RayOrgin.Transform.Forward, out Hit)
+ /// {
+ /// position = Hit.Collider.Position;
+ /// transform = Hit.Collider.Transform;
+ /// point = Hit.Point;
+ /// normal = Hit.Normal;
+ /// rot = .GetRotacionFromNormal(normal,transform);
+ /// point = .SnapToRotatedGridWithOffset(point,position,Offset,rot,GridSize);
+ /// SomeObject.Position = point;
+ /// }
+ /// }
+ /// }
+ ///
+ ///
+ ///
+ /// The position to snap.
+ /// The center point.
+ /// The rotation of the grid.
+ /// The size of the grid.
+ /// The local grid offset to applay after snaping
+ ///
+ public static Vector3 SnapToRotatedGridWithOffset(Vector3 InPoint, Vector3 InCenterPoint, Vector3 InOffset, Quaternion InOrientation, Vector3 InGridSize)
+ {
+ return ((SnapToGrid((InPoint - InCenterPoint) * InOrientation.Conjugated(), InGridSize) + InOffset) * InOrientation) + InCenterPoint;
+ }
+
///
/// Adds two vectors.
///
diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h
index 950d730c5..b8f074b73 100644
--- a/Source/Engine/Core/Math/Vector3.h
+++ b/Source/Engine/Core/Math/Vector3.h
@@ -927,6 +927,47 @@ public:
/// The second vector.
/// The angle (in radians).
static FLAXENGINE_API T Angle(const Vector3Base& from, const Vector3Base& to);
+
+ ///
+ /// Snaps the input position into the grid.
+ ///
+ /// The position to snap.
+ /// The size of the grid.
+ /// The position snapped to the grid.
+ static Vector3 SnapToGrid(const Vector3& pos, Vector3 gridSize)
+ {
+ pos.X = Math::Ceil((pos.X - (gridSize.X * 0.5f)) / gridSize.X) * gridSize.X;
+ pos.Y = Math::Ceil((pos.Y - (gridSize.Y * 0.5f)) / gridSize.Y) * gridSize.Y;
+ pos.Z = Math::Ceil((pos.Z - (gridSize.Z * 0.5f)) / gridSize.Z) * gridSize.Z;
+ return pos;
+ }
+
+ ///
+ /// Snaps the on to rotate grid.
+ /// for world aligned grid snapping use instead
+ ///
+ /// The position to snap.
+ /// The center point.
+ /// The rotation of the grid.
+ /// The size of the grid.
+ /// The position snapped to the grid.
+ static Vector3 SnapToRotatedGrid(const Vector3& InPoint, const Vector3& InCenterPoint, const Quaternion& InOrientation, const Vector3& InGridSize)
+ {
+ return (Vector3::SnapToGrid((InPoint - InCenterPoint) * InOrientation.Conjugated(), InGridSize) * InOrientation) + InCenterPoint;
+ }
+ ///
+ /// The same as but with local offset applied after point is spapend
+ ///
+ /// The position to snap.
+ /// The center point.
+ /// The rotation of the grid.
+ /// The size of the grid.
+ /// The local grid offset to applay after snaping
+ ///
+ static Vector3 SnapToRotatedGridWithOffset(const Vector3& InPoint, const Vector3& InCenterPoint, const Vector3& InOffset, const Quaternion& InOrientation, const Vector3& InGridSize)
+ {
+ return ((Vector3::SnapToGrid((InPoint - InCenterPoint) * InOrientation.Conjugated(), InGridSize) + InOffset) * InOrientation) + InCenterPoint;
+ }
};
template