Skip to content

Commit

Permalink
Added Quaternion::FromDirection.
Browse files Browse the repository at this point in the history
Allow to rotate camera given a direction.
  • Loading branch information
Wolftein committed Nov 8, 2024
1 parent 7c89613 commit 66d0f10
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
14 changes: 14 additions & 0 deletions Source/Public/Aurora.Graphic/Camera.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,20 @@ namespace Graphic
mDirty = true;
}

// -=(Undocumented)=-
void SetRotation(Ref<const Vector3f> Direction, Ref<const Vector3f> Up)
{
mTransformation.SetRotation(Quaternionf::FromDirection(Direction, Up));
mDirty = true;
}

// -=(Undocumented)=-
void SetRotation(Ref<const Vector3f> Eye, Ref<const Vector3f> Focus, Ref<const Vector3f> Up)
{
mTransformation.SetRotation(Quaternionf::FromDirection(Focus - Eye, Up));
mDirty = true;
}

// -=(Undocumented)=-
Ref<const Quaternionf> GetRotation() const
{
Expand Down
63 changes: 53 additions & 10 deletions Source/Public/Aurora.Math/Quaternion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,18 @@ inline namespace Math
Vector3<Base> GetForward() const
{
return Vector3<Base>(
2 * (mComplexes.GetX() * mComplexes.GetZ() + mReal * mComplexes.GetY()),
2 * (mComplexes.GetY() * mComplexes.GetZ() - mReal * mComplexes.GetX()),
1 - 2 * (mComplexes.GetX() * mComplexes.GetX() + mComplexes.GetY() * mComplexes.GetY()));
2.0 * (mComplexes.GetX() * mComplexes.GetZ() + mReal * mComplexes.GetY()),
2.0 * (mComplexes.GetY() * mComplexes.GetZ() - mReal * mComplexes.GetX()),
1.0 - 2.0 * (mComplexes.GetX() * mComplexes.GetX() + mComplexes.GetY() * mComplexes.GetY()));
}

// -=(Undocumented)=-
Vector3<Base> GetUp() const
{
return Vector3<Base>(
2 * (mComplexes.GetX() * mComplexes.GetY() - mReal * mComplexes.GetZ()),
1 - 2 * (mComplexes.GetX() * mComplexes.GetX() + mComplexes.GetZ() * mComplexes.GetZ()),
2 * (mComplexes.GetY() * mComplexes.GetZ() + mReal * mComplexes.GetX()));
2.0 * (mComplexes.GetX() * mComplexes.GetY() - mReal * mComplexes.GetZ()),
1.0 - 2.0 * (mComplexes.GetX() * mComplexes.GetX() + mComplexes.GetZ() * mComplexes.GetZ()),
2.0 * (mComplexes.GetY() * mComplexes.GetZ() + mReal * mComplexes.GetX()));
}

// -=(Undocumented)=-
Expand Down Expand Up @@ -128,18 +128,18 @@ inline namespace Math
// -=(Undocumented)=-
Quaternion<Base> operator*(Ref<const Quaternion<Base>> Other) const
{
const Vector3<Base> Complexes
= Other.mComplexes * mReal + mComplexes * Other.mReal
const Vector3<Base> Complexes = Other.mComplexes * mReal + mComplexes * Other.mReal
+ Vector3<Base>::Cross(mComplexes, Other.mComplexes);
return Quaternion<Base>(Complexes, mReal * Other.mReal - mComplexes.Dot(Other.mComplexes));
}

// -=(Undocumented)=-
Vector3<Base> operator*(Ref<const Vector3<Base>> Vector) const
{
const Vector3<Base> Cross = Vector3<Base>::Cross(mComplexes, Vector);

const Base Real = mReal + mReal;
return Real * Vector3<Base>::Cross(mComplexes, Vector)
+ (Real * mReal - 1) * Vector + 2 * mComplexes.Dot(Vector) * mComplexes;
return Real * Cross + (Real * mReal - 1) * Vector + 2 * mComplexes.Dot(Vector) * mComplexes;
}

// -=(Undocumented)=-
Expand Down Expand Up @@ -194,6 +194,49 @@ inline namespace Math
return Quaternion<Base>(- Value.mComplexes, Value.mReal);
}

// -=(Undocumented)=-
static Quaternion<Base> FromDirection(Ref<const Vector3<Base>> Direction, Ref<const Vector3<Base>> Up)
{
const Vector3<Base> vForward = Vector3<Base>::Normalize(Direction);
const Vector3<Base> vRight = Vector3<Base>::Normalize(Vector3<Base>::Cross(Up, vForward));
const Vector3<Base> vUp = Vector3<Base>::Cross(vForward, vRight);

const Base M00 = vRight.GetX();
const Base M01 = vRight.GetY();
const Base M02 = vRight.GetZ();
const Base M10 = vUp.GetX();
const Base M11 = vUp.GetY();
const Base M12 = vUp.GetZ();
const Base M20 = vForward.GetX();
const Base M21 = vForward.GetY();
const Base M22 = vForward.GetZ();

if (const Base Trace = M00 + M11 + M22; Trace > 0.0)
{
const Base InvSqrt = 0.5 / Sqrt(Trace + 1.0);
return Quaternion<Base>(
(M12 - M21) * InvSqrt, (M20 - M02) * InvSqrt, (M01 - M10) * InvSqrt, 0.25 / InvSqrt);
}
else if (M00 > M11 && M00 > M22)
{
const Base InvSqrt = 2.0 * Sqrt(1.0 + M00 - M11 - M22);
return Quaternion<Base>(
0.25 * InvSqrt, (M10 + M01) / InvSqrt, (M20 + M02) / InvSqrt, (M12 - M21) / InvSqrt);
}
else if (M11 > M22)
{
const Base InvSqrt = 2.0 * Sqrt(1.0 + M11 - M00 - M22);
return Quaternion<Base>(
(M10 + M01) / InvSqrt, 0.25 * InvSqrt, (M21 + M12) / InvSqrt, (M20 - M02) / InvSqrt);
}
else
{
const Base InvSqrt = 2.0 * Sqrt(1.0 + M22 - M00 - M11);
return Quaternion<Base>(
(M20 + M02) / InvSqrt, (M21 + M12) / InvSqrt, 0.25 * InvSqrt, (M01 - M10) / InvSqrt);
}
}

// -=(Undocumented)=-
static constexpr Quaternion<Base> FromAngles(Base Angle, Ref<const Vector3<Base>> Axis)
{
Expand Down

0 comments on commit 66d0f10

Please sign in to comment.