Merge branch 'cNori-Math'
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "Matrix3x3.h"
|
||||
#include "Math.h"
|
||||
#include "../Types/String.h"
|
||||
#include "Engine/Core/Math/Transform.h"
|
||||
|
||||
Quaternion Quaternion::Zero(0, 0, 0, 0);
|
||||
Quaternion Quaternion::One(1, 1, 1, 1);
|
||||
@@ -537,3 +538,14 @@ void Quaternion::RotationYawPitchRoll(float yaw, float pitch, float roll, Quater
|
||||
result.Y = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
|
||||
result.Z = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;
|
||||
}
|
||||
|
||||
Quaternion Quaternion::GetRotationFromNormal(const Vector3& normal, const Transform& reference)
|
||||
{
|
||||
Float3 up = reference.GetUp();
|
||||
const float dot = Vector3::Dot(normal, up);
|
||||
if (Math::NearEqual(Math::Abs(dot), 1))
|
||||
{
|
||||
up = reference.GetRight();
|
||||
}
|
||||
return Quaternion::LookRotation(normal, up);
|
||||
}
|
||||
|
||||
@@ -1483,6 +1483,45 @@ namespace FlaxEngine
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets rotation from a normal in relation to a transform.<br/>
|
||||
/// This function is especially useful for axis aligned faces,
|
||||
/// and with <seealso cref="Physics.RayCast(Vector3, Vector3, out RayCastHit, float, uint, bool)"/>.
|
||||
///
|
||||
/// <example><para><b>Example code:</b></para>
|
||||
/// <code>
|
||||
/// <see langword="public" /> <see langword="class" /> GetRotationFromNormalExample : <see cref="Script"/><br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> RayOrigin;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> SomeObject;<br/>
|
||||
/// <see langword="public" /> <see langword="override" /> <see langword="void" /> <see cref="Script.OnFixedUpdate"/><br/>
|
||||
/// {<br/>
|
||||
/// <see langword="if" /> (<see cref="Physics"/>.RayCast(RayOrigin.Position, RayOrigin.Transform.Forward, out <see cref="RayCastHit"/> hit)
|
||||
/// {<br/>
|
||||
/// <see cref="Vector3"/> position = hit.Collider.Position;
|
||||
/// <see cref="Transform"/> transform = hit.Collider.Transform;
|
||||
/// <see cref="Vector3"/> point = hit.Point;
|
||||
/// <see cref="Vector3"/> normal = hit.Normal;
|
||||
/// <see cref="Quaternion"/> rot = <see cref="Quaternion"/>.GetRotationFromNormal(normal,transform);
|
||||
/// SomeObject.Position = point;
|
||||
/// SomeObject.Orientation = rot;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="normal">The normal vector.</param>
|
||||
/// <param name="reference">The reference transform.</param>
|
||||
/// <returns>The rotation from the normal vector.</returns>
|
||||
public static Quaternion GetRotationFromNormal(Vector3 normal, Transform reference)
|
||||
{
|
||||
Float3 up = reference.Up;
|
||||
var dot = Vector3.Dot(normal, up);
|
||||
if (Mathf.NearEqual(Math.Abs(dot), 1))
|
||||
up = reference.Right;
|
||||
return LookRotation(normal, up);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two quaternions.
|
||||
/// </summary>
|
||||
|
||||
@@ -660,6 +660,14 @@ 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);
|
||||
|
||||
/// <summary>
|
||||
/// Gets rotation from a normal in relation to a transform. This function is especially useful for axis aligned faces, and with <seealso cref="Physics::RayCast"/>.
|
||||
/// </summary>
|
||||
/// <param name="normal">The normal vector.</param>
|
||||
/// <param name="reference">The reference transform.</param>
|
||||
/// <returns>The rotation from the normal vector.</returns>
|
||||
static Quaternion GetRotationFromNormal(const Vector3& normal, const Transform& reference);
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -252,3 +252,9 @@ void Transform::Lerp(const Transform& t1, const Transform& t2, float amount, Tra
|
||||
Quaternion::Slerp(t1.Orientation, t2.Orientation, amount, result.Orientation);
|
||||
Float3::Lerp(t1.Scale, t2.Scale, amount, result.Scale);
|
||||
}
|
||||
|
||||
Transform Transform::AlignRotationToNormalAndSnapToGrid(const Vector3& point, const Vector3& normal, const Vector3& normalOffset, const Transform& relativeTo, const Vector3& gridSize, const Float3& scale)
|
||||
{
|
||||
Quaternion rot = Quaternion::GetRotationFromNormal(normal, relativeTo);
|
||||
return Transform(Vector3::SnapToGrid(point, gridSize, rot, relativeTo.Translation, normalOffset), rot, scale);
|
||||
}
|
||||
|
||||
@@ -478,6 +478,96 @@ namespace FlaxEngine
|
||||
Float3.Lerp(ref start.Scale, ref end.Scale, amount, out result.Scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines the functions:<br/>
|
||||
/// <see cref="Vector3.SnapToGrid(FlaxEngine.Vector3,FlaxEngine.Vector3)"/>,<br/>
|
||||
/// <see cref="Quaternion.GetRotationFromNormal"/>.
|
||||
/// <example><para><b>Example code:</b></para>
|
||||
/// <code>
|
||||
/// <see langword="public" /> <see langword="class" /> AlignRotationToObjectAndSnapToGridExample : <see cref="Script"/><br/>
|
||||
/// <see langword="public" /> <see cref="Vector3"/> Offset = new Vector3(0, 0, 50f);<br/>
|
||||
/// <see langword="public" /> <see cref="Vector3"/> GridSize = <see cref="Vector3.One"/> * 20.0f;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> RayOrigin;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> SomeObject;<br/>
|
||||
/// <see langword="public" /> <see langword="override" /> <see langword="void" /> <see cref="Script.OnFixedUpdate"/><br/>
|
||||
/// {<br/>
|
||||
/// <see langword="if" /> (<see cref="Physics"/>.RayCast(RayOrigin.Position, RayOrigin.Transform.Forward, out <see cref="RayCastHit"/> hit)
|
||||
/// {<br/>
|
||||
/// <see cref="Transform"/> transform = hit.Collider.Transform;
|
||||
/// <see cref="Vector3"/> point = hit.Point;
|
||||
/// <see cref="Vector3"/> normal = hit.Normal;
|
||||
/// SomeObject.Transform = <see cref="Transform"/>.AlignRotationToNormalAndSnapToGrid
|
||||
/// (
|
||||
/// point,
|
||||
/// normal,
|
||||
/// Offset,
|
||||
/// transform,
|
||||
/// SomeObject.Scale,
|
||||
/// GridSize,
|
||||
/// Float3.One
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="point">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <param name="normalOffset">The local grid offset to apply after snapping.</param>
|
||||
/// <param name="normal">The normal vector.</param>
|
||||
/// <param name="relativeTo">The relative transform.</param>
|
||||
/// <param name="scale">The scale to apply to the transform.</param>
|
||||
/// <returns>The rotated and snapped transform.</returns>
|
||||
public static Transform AlignRotationToNormalAndSnapToGrid(Vector3 point, Vector3 normal, Vector3 normalOffset, Transform relativeTo, Vector3 gridSize, Float3 scale)
|
||||
{
|
||||
Quaternion rot = Quaternion.GetRotationFromNormal(normal, relativeTo);
|
||||
return new Transform(Vector3.SnapToGrid(point, gridSize, rot, relativeTo.Translation, normalOffset), rot, scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines the functions:<br/>
|
||||
/// <see cref="Vector3.SnapToGrid(FlaxEngine.Vector3,FlaxEngine.Vector3)"/>,<br/>
|
||||
/// <see cref="Quaternion.GetRotationFromNormal"/>.
|
||||
/// <example><para><b>Example code:</b></para>
|
||||
/// <code>
|
||||
/// <see langword="public" /> <see langword="class" /> AlignRotationToObjectAndSnapToGridExample : <see cref="Script"/><br/>
|
||||
/// <see langword="public" /> <see cref="Vector3"/> Offset = new Vector3(0, 0, 50f);<br/>
|
||||
/// <see langword="public" /> <see cref="Vector3"/> GridSize = <see cref="Vector3.One"/> * 20.0f;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> RayOrigin;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> SomeObject;<br/>
|
||||
/// <see langword="public" /> <see langword="override" /> <see langword="void" /> <see cref="Script.OnFixedUpdate"/><br/>
|
||||
/// {<br/>
|
||||
/// <see langword="if" /> (<see cref="Physics"/>.RayCast(RayOrigin.Position, RayOrigin.Transform.Forward, out <see cref="RayCastHit"/> hit)
|
||||
/// {<br/>
|
||||
/// <see cref="Transform"/> transform = hit.Collider.Transform;
|
||||
/// <see cref="Vector3"/> point = hit.Point;
|
||||
/// <see cref="Vector3"/> normal = hit.Normal;
|
||||
/// SomeObject.Transform = <see cref="Transform"/>.AlignRotationToNormalAndSnapToGrid
|
||||
/// (
|
||||
/// point,
|
||||
/// normal,
|
||||
/// Offset,
|
||||
/// transform,
|
||||
/// GridSize
|
||||
/// );
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="point">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <param name="normalOffset">The local grid offset to apply after snapping.</param>
|
||||
/// <param name="normal">The normal vector.</param>
|
||||
/// <param name="relativeTo">The relative transform.</param>
|
||||
/// <returns>The rotated and snapped transform with scale <see cref="Float3.One"/>.</returns>
|
||||
public static Transform AlignRotationToNormalAndSnapToGrid(Vector3 point, Vector3 normal, Vector3 normalOffset, Transform relativeTo, Vector3 gridSize)
|
||||
{
|
||||
return AlignRotationToNormalAndSnapToGrid(point, normal, normalOffset, relativeTo, gridSize, Float3.One);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
|
||||
@@ -291,6 +291,20 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines the functions: <br/>
|
||||
/// <see cref="SnapToGrid"/>,<br/>
|
||||
/// <see cref="GetRotationFromNormal"/>.
|
||||
/// </summary>
|
||||
/// <param name="point">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <param name="normalOffset">The local grid offset to apply after snapping.</param>
|
||||
/// <param name="normal">The normal vector.</param>
|
||||
/// <param name="relativeTo">The relative transform.</param>
|
||||
/// <param name="scale">The scale to apply to the transform.</param>
|
||||
/// <returns>The rotated and snapped transform.</returns>
|
||||
static Transform AlignRotationToNormalAndSnapToGrid(const Vector3& point, const Vector3& normal, const Vector3& normalOffset, const Transform& relativeTo, const Vector3& gridSize, const Float3& scale = Float3::One);
|
||||
|
||||
public:
|
||||
FORCE_INLINE Transform operator*(const Transform& other) const
|
||||
{
|
||||
|
||||
@@ -324,6 +324,20 @@ float Float3::Angle(const Float3& from, const Float3& to)
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
template<>
|
||||
Float3 Float3::SnapToGrid(const Float3& pos, const Float3& gridSize)
|
||||
{
|
||||
return Float3(Math::Ceil((pos.X - (gridSize.X * 0.5f)) / gridSize.X) * gridSize.X,
|
||||
Math::Ceil((pos.Y - (gridSize.Y * 0.5f)) / gridSize.Y) * gridSize.Y,
|
||||
Math::Ceil((pos.Z - (gridSize.Z * 0.5f)) / gridSize.Z) * gridSize.Z);
|
||||
}
|
||||
|
||||
template<>
|
||||
Float3 Float3::SnapToGrid(const Float3& point, const Float3& gridSize, const Quaternion& gridOrientation, const Float3& gridOrigin, const Float3& offset)
|
||||
{
|
||||
return (gridOrientation * (gridOrientation.Conjugated() * SnapToGrid(point - gridOrigin, gridSize) + offset)) + gridOrigin;
|
||||
}
|
||||
|
||||
// Double
|
||||
|
||||
static_assert(sizeof(Double3) == 24, "Invalid Double3 type size.");
|
||||
@@ -638,6 +652,20 @@ double Double3::Angle(const Double3& from, const Double3& to)
|
||||
return Math::Acos(dot);
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3 Double3::SnapToGrid(const Double3& pos, const Double3& gridSize)
|
||||
{
|
||||
return Double3(Math::Ceil((pos.X - (gridSize.X * 0.5)) / gridSize.X) * gridSize.X,
|
||||
Math::Ceil((pos.Y - (gridSize.Y * 0.5)) / gridSize.Y) * gridSize.Y,
|
||||
Math::Ceil((pos.Z - (gridSize.Z * 0.5)) / gridSize.Z) * gridSize.Z);
|
||||
}
|
||||
|
||||
template<>
|
||||
Double3 Double3::SnapToGrid(const Double3& point, const Double3& gridSize, const Quaternion& gridOrientation, const Double3& gridOrigin, const Double3& offset)
|
||||
{
|
||||
return (gridOrientation * (gridOrientation.Conjugated() * SnapToGrid(point - gridOrigin, gridSize) + offset)) + gridOrigin;
|
||||
}
|
||||
|
||||
// Int
|
||||
|
||||
static_assert(sizeof(Int3) == 12, "Invalid Int3 type size.");
|
||||
@@ -852,3 +880,17 @@ int32 Int3::Angle(const Int3& from, const Int3& to)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3 Int3::SnapToGrid(const Int3& pos, const Int3& gridSize)
|
||||
{
|
||||
return Int3(((pos.X - (gridSize.X / 2)) / gridSize.X) * gridSize.X,
|
||||
((pos.Y - (gridSize.Y / 2)) / gridSize.Y) * gridSize.Y,
|
||||
((pos.Z - (gridSize.Z / 2)) / gridSize.Z) * gridSize.Z);
|
||||
}
|
||||
|
||||
template<>
|
||||
Int3 Int3::SnapToGrid(const Int3& point, const Int3& gridSize, const Quaternion& gridOrientation, const Int3& gridOrigin, const Int3& offset)
|
||||
{
|
||||
return (gridOrientation * (gridOrientation.Conjugated() * SnapToGrid(point - gridOrigin, gridSize) + offset)) + gridOrigin;
|
||||
}
|
||||
|
||||
@@ -1672,7 +1672,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps the input position into the grid.
|
||||
/// Snaps the input position onto the grid.
|
||||
/// </summary>
|
||||
/// <param name="pos">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
@@ -1685,6 +1685,44 @@ namespace FlaxEngine
|
||||
return pos;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps the <paramref name="point"/> onto the rotated grid.<br/>
|
||||
/// For world aligned grid snapping use <b><see cref="SnapToGrid(FlaxEngine.Vector3,FlaxEngine.Vector3)"/></b> instead.
|
||||
/// <example><para><b>Example code:</b></para>
|
||||
/// <code>
|
||||
/// <see langword="public" /> <see langword="class" /> SnapToGridExample : <see cref="Script"/><br/>
|
||||
/// <see langword="public" /> <see cref="Vector3"/> GridSize = <see cref="Vector3.One"/> * 20.0f;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> RayOrigin;<br/>
|
||||
/// <see langword="public" /> <see cref="Actor"/> SomeObject;<br/>
|
||||
/// <see langword="public" /> <see langword="override" /> <see langword="void" /> <see cref="Script.OnFixedUpdate"/><br/>
|
||||
/// {<br/>
|
||||
/// <see langword="if" /> (<see cref="Physics"/>.RayCast(RayOrigin.Position, RayOrigin.Transform.Forward, out <see cref="RayCastHit"/> hit)
|
||||
/// {<br/>
|
||||
/// <see cref="Vector3"/> position = hit.Collider.Position;
|
||||
/// <see cref="FlaxEngine.Transform"/> transform = hit.Collider.Transform;
|
||||
/// <see cref="Vector3"/> point = hit.Point;
|
||||
/// <see cref="Vector3"/> normal = hit.Normal;
|
||||
/// //Get rotation from normal relative to collider transform
|
||||
/// <see cref="Quaternion"/> rot = <see cref="Quaternion"/>.GetRotationFromNormal(normal, transform);
|
||||
/// point = <see cref="Vector3"/>.SnapToGrid(point, GridSize, rot, position);
|
||||
/// SomeObject.Position = point;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </summary>
|
||||
/// <param name="point">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <param name="gridOrientation">The rotation of the grid.</param>
|
||||
/// <param name="gridOrigin">The center point of the grid.</param>
|
||||
/// <param name="offset">The local position offset applied to the snapped position before grid rotation.</param>
|
||||
/// <returns>The position snapped to the grid.</returns>
|
||||
public static Vector3 SnapToGrid(Vector3 point, Vector3 gridSize, Quaternion gridOrientation, Vector3 gridOrigin, Vector3 offset)
|
||||
{
|
||||
return ((SnapToGrid(point - gridOrigin, gridSize) * gridOrientation.Conjugated() + offset) * gridOrientation) + gridOrigin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
|
||||
@@ -927,6 +927,25 @@ public:
|
||||
/// <param name="to">The second vector.</param>
|
||||
/// <returns>The angle (in radians).</returns>
|
||||
static FLAXENGINE_API T Angle(const Vector3Base& from, const Vector3Base& to);
|
||||
|
||||
/// <summary>
|
||||
/// Snaps the input position onto the grid.
|
||||
/// </summary>
|
||||
/// <param name="pos">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <returns>The position snapped to the grid.</returns>
|
||||
static FLAXENGINE_API Vector3Base SnapToGrid(const Vector3Base& pos, const Vector3Base& gridSize);
|
||||
|
||||
/// <summary>
|
||||
/// Snaps the <paramref name="point"/> onto the rotated grid. For world aligned grid snapping use <b><see cref="SnapToGrid"/></b> instead.
|
||||
/// </summary>
|
||||
/// <param name="point">The position to snap.</param>
|
||||
/// <param name="gridSize">The size of the grid.</param>
|
||||
/// <param name="gridOrigin">The center point of the grid.</param>
|
||||
/// <param name="gridOrientation">The rotation of the grid.</param>
|
||||
/// <param name="offset">The local position offset applied to the snapped position before grid rotation.</param>
|
||||
/// <returns>The position snapped to the grid.</returns>
|
||||
static FLAXENGINE_API Vector3Base SnapToGrid(const Vector3Base& point, const Vector3Base& gridSize, const Quaternion& gridOrientation, const Vector3Base& gridOrigin = Zero, const Vector3Base& offset = Zero);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
||||
Reference in New Issue
Block a user