Apply reviewer suggestions

Signed-off-by: Nemerle <nemerle5+git@gmail.com>
This commit is contained in:
Nemerle
2021-12-17 16:02:33 +01:00
449 changed files with 11205 additions and 5685 deletions
@@ -18,7 +18,7 @@
namespace AZ::Data
{
namespace Internal
namespace DataStreamInternal
{
struct AssetDataStreamPrivate
{
@@ -39,7 +39,7 @@ namespace AZ::Data
}
void BlockUntilReadComplete()
{
AZStd::unique_lock<AZStd::mutex> lock(m_readRequestMutex);
AZStd::unique_lock lock(m_readRequestMutex);
m_readRequestActive.wait(
lock,
[this]
@@ -59,9 +59,10 @@ namespace AZ::Data
}
};
} // namespace Internal
AssetDataStream::AssetDataStream(AZ::IO::IStreamerTypes::RequestMemoryAllocator* bufferAllocator)
: m_bufferAllocator(bufferAllocator ? bufferAllocator : &m_defaultAllocator)
, m_privateData(new Internal::AssetDataStreamPrivate)
: m_privateData(AZStd::make_unique<DataStreamInternal::AssetDataStreamPrivate>())
, m_bufferAllocator(bufferAllocator ? bufferAllocator : &m_defaultAllocator)
{
ClearInternalStateData();
}
@@ -72,7 +73,6 @@ namespace AZ::Data
{
Close();
}
delete m_privateData;
}
@@ -9,8 +9,8 @@
#include <AzCore/IO/GenericStreams.h>
#include <AzCore/IO/IStreamerTypes.h>
#include <AzCore/std/function/function_template.h>
#include <AzCore/std/functional.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
namespace AZStd
{
@@ -20,7 +20,7 @@ namespace AZStd
namespace AZ::Data
{
namespace Internal
namespace DataStreamInternal
{
struct AssetDataStreamPrivate;
}
@@ -100,7 +100,7 @@ namespace AZ::Data
void ClearInternalStateData();
Internal::AssetDataStreamPrivate* m_privateData;
AZStd::unique_ptr<DataStreamInternal::AssetDataStreamPrivate> m_privateData;
//! The allocator to use for allocating / deallocating asset buffers
AZ::IO::IStreamerTypes::RequestMemoryAllocator* m_bufferAllocator{ nullptr };
@@ -74,7 +74,7 @@ namespace AZ::IO
void CreateDedicatedCache(FileRequest* request, Requests::CreateDedicatedCacheData& data);
void DestroyDedicatedCache(FileRequest* request, Requests::DestroyDedicatedCacheData& data);
void ReadFile(FileRequest* request, AZ::IO::Requests::ReadData& data);
void ReadFile(FileRequest* request, Requests::ReadData& data);
size_t FindCache(const RequestPath& filename, FileRange range);
size_t FindCache(const RequestPath& filename, u64 offset);
@@ -153,7 +153,6 @@ namespace AZ::IO::Requests
namespace AZ::IO
{
using namespace Requests;
//
// FileRequest
//
@@ -176,14 +175,14 @@ namespace AZ::IO
m_parent = request->m_request.m_parent;
request->m_request.m_parent = this;
m_dependencies++;
m_command.emplace<ExternalRequestData>(AZStd::move(request));
m_command.emplace<Requests::ExternalRequestData>(AZStd::move(request));
}
void FileRequest::CreateRequestPathStore(FileRequest* parent, RequestPath path)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'CreateRequestPathStore', but another task was already assigned.");
m_command.emplace<RequestPathStoreData>(AZStd::move(path));
m_command.emplace<Requests::RequestPathStoreData>(AZStd::move(path));
SetOptionalParent(parent);
}
@@ -192,7 +191,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'ReadRequest', but another task was already assigned.");
m_command.emplace<ReadRequestData>(AZStd::move(path), output, outputSize, offset, size, deadline, priority);
m_command.emplace<Requests::ReadRequestData>(AZStd::move(path), output, outputSize, offset, size, deadline, priority);
}
void FileRequest::CreateReadRequest(RequestPath path, IStreamerTypes::RequestMemoryAllocator* allocator, u64 offset, u64 size,
@@ -200,7 +199,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'ReadRequest', but another task was already assigned.");
m_command.emplace<ReadRequestData>(AZStd::move(path), allocator, offset, size, deadline, priority);
m_command.emplace<Requests::ReadRequestData>(AZStd::move(path), allocator, offset, size, deadline, priority);
}
void FileRequest::CreateRead(FileRequest* parent, void* output, u64 outputSize, const RequestPath& path,
@@ -208,7 +207,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Read', but another task was already assigned.");
m_command.emplace<ReadData>(output, outputSize, AZStd::move(path), offset, size, sharedRead);
m_command.emplace<Requests::ReadData>(output, outputSize, AZStd::move(path), offset, size, sharedRead);
SetOptionalParent(parent);
}
@@ -223,7 +222,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'CompressedRead', but another task was already assigned.");
m_command.emplace<CompressedReadData>(AZStd::move(compressionInfo), output, readOffset, readSize);
m_command.emplace<Requests::CompressedReadData>(AZStd::move(compressionInfo), output, readOffset, readSize);
SetOptionalParent(parent);
}
@@ -231,7 +230,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Wait', but another task was already assigned.");
m_command.emplace<WaitData>();
m_command.emplace<Requests::WaitData>();
SetOptionalParent(parent);
}
@@ -239,21 +238,21 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'FileExistsCheck', but another task was already assigned.");
m_command.emplace<FileExistsCheckData>(path);
m_command.emplace<Requests::FileExistsCheckData>(path);
}
void FileRequest::CreateFileMetaDataRetrieval(const RequestPath& path)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'FileMetaDataRetrieval', but another task was already assigned.");
m_command.emplace<FileMetaDataRetrievalData>(path);
m_command.emplace<Requests::FileMetaDataRetrievalData>(path);
}
void FileRequest::CreateCancel(FileRequestPtr target)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Cancel', but another task was already assigned.");
m_command.emplace<CancelData>(AZStd::move(target));
m_command.emplace<Requests::CancelData>(AZStd::move(target));
}
void FileRequest::CreateReschedule(FileRequestPtr target, AZStd::chrono::system_clock::time_point newDeadline,
@@ -261,28 +260,28 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Reschedule', but another task was already assigned.");
m_command.emplace<RescheduleData>(AZStd::move(target), newDeadline, newPriority);
m_command.emplace<Requests::RescheduleData>(AZStd::move(target), newDeadline, newPriority);
}
void FileRequest::CreateFlush(RequestPath path)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Flush', but another task was already assigned.");
m_command.emplace<FlushData>(AZStd::move(path));
m_command.emplace<Requests::FlushData>(AZStd::move(path));
}
void FileRequest::CreateFlushAll()
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'FlushAll', but another task was already assigned.");
m_command.emplace<FlushAllData>();
m_command.emplace<Requests::FlushAllData>();
}
void FileRequest::CreateDedicatedCacheCreation(RequestPath path, const FileRange& range, FileRequest* parent)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'CreateDedicateCache', but another task was already assigned.");
m_command.emplace<CreateDedicatedCacheData>(AZStd::move(path), range);
m_command.emplace<Requests::CreateDedicatedCacheData>(AZStd::move(path), range);
SetOptionalParent(parent);
}
@@ -290,7 +289,7 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'DestroyDedicateCache', but another task was already assigned.");
m_command.emplace<DestroyDedicatedCacheData>(AZStd::move(path), range);
m_command.emplace<Requests::DestroyDedicatedCacheData>(AZStd::move(path), range);
SetOptionalParent(parent);
}
@@ -298,14 +297,14 @@ namespace AZ::IO
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Report', but another task was already assigned.");
m_command.emplace<ReportData>(reportType);
m_command.emplace<Requests::ReportData>(reportType);
}
void FileRequest::CreateCustom(AZStd::any data, bool failWhenUnhandled, FileRequest* parent)
{
AZ_Assert(AZStd::holds_alternative<AZStd::monostate>(m_command),
"Attempting to set FileRequest to 'Custom', but another task was already assigned.");
m_command.emplace<CustomData>(AZStd::move(data), failWhenUnhandled);
m_command.emplace<Requests::CustomData>(AZStd::move(data), failWhenUnhandled);
SetOptionalParent(parent);
}
@@ -429,7 +428,7 @@ namespace AZ::IO
const FileRequest* current = this;
while (current)
{
auto* link = AZStd::get_if<ExternalRequestData>(&current->m_command);
auto* link = AZStd::get_if<Requests::ExternalRequestData>(&current->m_command);
if (!link)
{
current = current->m_parent;
@@ -343,7 +343,7 @@ namespace AZ::IO
m_numRunningJobs == 0;
}
void FullFileDecompressor::PrepareReadRequest(FileRequest* request, Requests::ReadRequestData &data)
void FullFileDecompressor::PrepareReadRequest(FileRequest* request, Requests::ReadRequestData& data)
{
CompressionInfo info;
if (CompressionUtils::FindCompressionInfo(info, data.m_path.GetRelativePath()))
@@ -8,9 +8,9 @@
#include <AzCore/IO/Streamer/Scheduler.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/IO/Streamer/FileRequest.h>
#include <AzCore/std/containers/deque.h>
#include <AzCore/std/sort.h>
@@ -37,9 +37,7 @@ namespace AZ::IO
m_threadData.m_streamStack = AZStd::move(streamStack);
}
Scheduler::~Scheduler()
{
}
Scheduler::~Scheduler() = default;
void Scheduler::Start(const AZStd::thread_desc& threadDesc)
{
@@ -60,13 +60,13 @@ namespace AZ::IO
AZ_PROFILE_FUNCTION(AzCore);
AZ_Assert(request, "PrepareRequest was provided a null request.");
if (AZStd::holds_alternative<Requests::ReadRequestData>(request->GetCommand()))
if (AZStd::holds_alternative<Requests::ReadRequestData>(request->GetCommand()))
{
auto& readRequest = AZStd::get<Requests::ReadRequestData>(request->GetCommand());
auto& readRequest = AZStd::get<Requests::ReadRequestData>(request->GetCommand());
FileRequest* read = m_context->GetNewInternalRequest();
read->CreateRead(request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path,
readRequest.m_offset, readRequest.m_size);
read->CreateRead(
request, readRequest.m_output, readRequest.m_outputSize, readRequest.m_path, readRequest.m_offset, readRequest.m_size);
m_context->PushPreparedRequest(read);
return;
}
@@ -23,9 +23,8 @@ namespace AZ
static constexpr char MissedDeadlinesName[] = "Missed deadlines";
#endif // AZ_STREAMER_ADD_EXTRA_PROFILING_INFO
StreamerContext::StreamerContext()
{
}
StreamerContext::StreamerContext() = default;
StreamerContext::~StreamerContext()
{
for (FileRequest* entry : m_internalRecycleBin)
@@ -228,7 +227,7 @@ namespace AZ
top->m_onCompletion(*top);
AZ_PROFILE_INTERVAL_END(AzCore, top);
}
if (parent)
{
AZ_Assert(parent->m_dependencies > 0,
@@ -7,11 +7,11 @@
*/
#pragma once
#include <AzCore/base.h>
#include <AzCore/IO/Streamer/Statistics.h>
#include <AzCore/IO/Streamer/StreamerConfiguration.h>
#include <AzCore/IO/Streamer/StreamerContext_Platform.h>
#include <AzCore/Statistics/RunningStatistic.h>
#include <AzCore/base.h>
#include <AzCore/std/containers/deque.h>
#include <AzCore/std/containers/queue.h>
#include <AzCore/std/containers/vector.h>
@@ -254,13 +254,13 @@ namespace AZ
Method("CreateFromMatrix3x3", &Quaternion::CreateFromMatrix3x3)->
Method("CreateFromMatrix4x4", &Quaternion::CreateFromMatrix4x4)->
Method("CreateFromAxisAngle", &Quaternion::CreateFromAxisAngle)->
Method("CreateFromScaledAxisAngle", &Quaternion::CreateFromScaledAxisAngle)->
Method("CreateShortestArc", &Quaternion::CreateShortestArc)->
Method("CreateFromEulerAnglesDegrees", &Quaternion::CreateFromEulerAnglesDegrees)
;
}
}
Quaternion Quaternion::CreateFromMatrix3x3(const Matrix3x3& m)
{
return CreateFromBasis(m.GetBasisX(), m.GetBasisY(), m.GetBasisZ());
@@ -430,4 +430,24 @@ namespace AZ
outAngle = 0.0f;
}
}
Vector3 Quaternion::ConvertToScaledAxisAngle() const
{
// Take the log of the quaternion to convert it to the exponential map
// and multiply it by 2.0 to bring it into the scaled axis-angle representation.
const AZ::Vector3 imaginary = GetImaginary();
const float length = imaginary.GetLength();
if (length < AZ::Constants::FloatEpsilon)
{
return imaginary * 2.0f;
}
else
{
const float halfAngle = acosf(AZ::GetClamp(GetW(), -1.0f, 1.0f));
// Multiply by 2.0 to convert the half angle into the full one.
return halfAngle * 2.0f * (imaginary / length);
}
}
}
@@ -77,6 +77,9 @@ namespace AZ
static Quaternion CreateFromAxisAngle(const Vector3& axis, float angle);
//! Create a quaternion from a scaled axis-angle representation.
static Quaternion CreateFromScaledAxisAngle(const Vector3& scaledAxisAngle);
static Quaternion CreateShortestArc(const Vector3& v1, const Vector3& v2);
//! Creates a quaternion using rotation in degrees about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis.
@@ -231,6 +234,9 @@ namespace AZ
//! @param[out] outAngle A float rotation angle around the axis in radians.
void ConvertToAxisAngle(Vector3& outAxis, float& outAngle) const;
//! Convert the quaternion into scaled axis-angle representation.
Vector3 ConvertToScaledAxisAngle() const;
//! Returns the imaginary (X/Y/Z) portion of the quaternion.
Vector3 GetImaginary() const;
@@ -109,6 +109,24 @@ namespace AZ
}
AZ_MATH_INLINE Quaternion Quaternion::CreateFromScaledAxisAngle(const Vector3& scaledAxisAngle)
{
const AZ::Vector3 exponentialMap = scaledAxisAngle / 2.0f;
const float halfAngle = exponentialMap.GetLength();
if (halfAngle < AZ::Constants::FloatEpsilon)
{
return AZ::Quaternion::CreateFromVector3AndValue(exponentialMap, 1.0f).GetNormalized();
}
else
{
float sin, cos;
SinCos(halfAngle, sin, cos);
return AZ::Quaternion::CreateFromVector3AndValue((sin / halfAngle) * exponentialMap, cos);
}
}
AZ_MATH_INLINE void Quaternion::StoreToFloat4(float* values) const
{
Simd::Vec4::StoreUnaligned(values, m_value);
@@ -105,6 +105,8 @@ void ScriptContextDebug::ConnectHook()
void ScriptContextDebug::DisconnectHook()
{
lua_sethook(m_context.NativeContext(), nullptr, 0, 0);
m_currentStackLevel = -1;
m_stepStackLevel = -1;
}
//=========================================================================
@@ -651,6 +653,11 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
context->PopCallstack();
}
context->m_currentStackLevel--;
if (context->m_currentStackLevel == -1)
{
context->m_stepStackLevel = -1;
}
}
else if (ar->event == LUA_HOOKLINE)
{
@@ -731,7 +738,7 @@ void AZ::LuaHook(lua_State* l, lua_Debug* ar)
//}
}
if (doBreak)
if (doBreak && bp->m_lineNumber > 0)
{
context->m_luaDebug = ar;
context->m_breakCallback(context, bp);
@@ -62,6 +62,7 @@ namespace AZ
TimeSystem::TimeSystem()
{
m_lastInvokedTimeUs = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
m_realLastInvokedTimeUs = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
AZ::Interface<ITime>::Register(this);
ITimeRequestBus::Handler::BusConnect();
}
@@ -101,7 +102,11 @@ namespace AZ
TimeUs TimeSystem::GetRealElapsedTimeUs() const
{
return static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
const TimeUs currentTime = static_cast<TimeUs>(AZStd::GetTimeNowMicroSecond());
m_realAccumulatedTimeUs += currentTime - m_realLastInvokedTimeUs;
m_realLastInvokedTimeUs = currentTime;
return m_realAccumulatedTimeUs;
}
TimeUs TimeSystem::GetSimulationTickDeltaTimeUs() const
@@ -64,6 +64,14 @@ namespace AZ
//! Mutable to allow GetElapsedTimeMs/TimeUs() to be a const functions.
mutable TimeUs m_accumulatedTimeUs = AZ::Time::ZeroTimeUs;
//! Used to calculate the delta time between calls to GetRealElapsedTimeMs/TimeUs().
//! Mutable to allow GetRealElapsedTimeMs/TimeUs() to be a const functions.
mutable TimeUs m_realLastInvokedTimeUs = AZ::Time::ZeroTimeUs;
//! Accumulates the delta time of GetRealElapsedTimeMs/TimeUs() calls.
//! Mutable to allow GetRealElapsedTimeMs/TimeUs() to be a const functions.
mutable TimeUs m_realAccumulatedTimeUs = AZ::Time::ZeroTimeUs;
//! The current game tick delta time.
//! Can be affected by time system cvars.
//! Updated in AdvanceTickDeltaTimes().
@@ -69,6 +69,15 @@ namespace UnitTest
return numAssertsFailed;
}
void ResetSuppressionSettingsToDefault()
{
m_suppressErrors = true;
m_suppressWarnings = true;
m_suppressAsserts = true;
m_suppressOutput = true;
m_suppressPrintf = true;
}
bool m_isAssertTest;
bool m_suppressErrors = true;
bool m_suppressWarnings = true;
@@ -254,27 +254,29 @@ namespace AZ::IO
else if (!m_pendingRequests.empty())
{
FileRequest* request = m_pendingRequests.front();
hasWorked = AZStd::visit([this, request](auto&& args)
{
using Command = AZStd::decay_t<decltype(args)>;
hasWorked = AZStd::visit(
[this, request](auto&& args)
{
using Command = AZStd::decay_t<decltype(args)>;
if constexpr (AZStd::is_same_v<Command, Requests::FileExistsCheckData>)
{
FileExistsRequest(request);
m_pendingRequests.pop_front();
return true;
}
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
{
FileMetaDataRetrievalRequest(request);
m_pendingRequests.pop_front();
return true;
}
else
{
AZ_Assert(false, "A request was added to StorageDriveWin's pending queue that isn't supported.");
return false;
}
}, request->GetCommand());
{
FileExistsRequest(request);
m_pendingRequests.pop_front();
return true;
}
else if constexpr (AZStd::is_same_v<Command, Requests::FileMetaDataRetrievalData>)
{
FileMetaDataRetrievalRequest(request);
m_pendingRequests.pop_front();
return true;
}
else
{
AZ_Assert(false, "A request was added to StorageDriveWin's pending queue that isn't supported.");
return false;
}
},
request->GetCommand());
}
return StreamStackEntry::ExecuteRequests() || hasFinalizedReads || hasWorked;
@@ -408,4 +408,106 @@ namespace UnitTest
Matrix4x4 m = Matrix4x4::CreateFromQuaternion(rotQuat);
AZ_TEST_ASSERT(m.IsClose(rotMatrix));
}
class QuaternionScaledAxisAngleConversionFixture
: public ::testing::TestWithParam<AZ::Quaternion>
{
public:
AZ::Quaternion GetAbs(const AZ::Quaternion& in)
{
// Take the shortest path for quaternions containing rotations bigger than 180.0°.
if (in.GetW() < 0.0f)
{
return -in;
}
return in;
}
};
static const AZ::Quaternion RotationRepresentationConversionTestQuats[] =
{
AZ::Quaternion::CreateIdentity(),
-AZ::Quaternion::CreateIdentity(),
AZ::Quaternion::CreateRotationX(AZ::Constants::TwoPi),
AZ::Quaternion::CreateRotationY(AZ::Constants::Pi),
AZ::Quaternion::CreateRotationZ(AZ::Constants::HalfPi),
AZ::Quaternion::CreateRotationX(AZ::Constants::QuarterPi),
AZ::Quaternion(0.64f, 0.36f, 0.48f, 0.48f),
AZ::Quaternion(0.70f, -0.34f, 0.10f, 0.62f),
AZ::Quaternion(-0.38f, 0.34f, 0.70f, -0.50f),
AZ::Quaternion(0.70f, -0.34f, -0.38f, 0.50f),
AZ::Quaternion(0.00f, 0.00f, -0.28f, 0.96f),
AZ::Quaternion(0.24f, -0.64f, 0.72f, 0.12f),
AZ::Quaternion(-0.66f, 0.62f, 0.42f, 0.06f)
};
TEST_P(QuaternionScaledAxisAngleConversionFixture, ScaledAxisAngleQuatRoundtripTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to scaled axis-angle representation.
const AZ::Vector3 scaledAxisAngle = testQuat.ConvertToScaledAxisAngle();
// Convert the scaled axis-angle back into a quaternion.
AZ::Quaternion backFromScaledAxisAngle = AZ::Quaternion::CreateFromScaledAxisAngle(scaledAxisAngle);
// Compare the original quaternion with the one after the conversion.
EXPECT_TRUE(testQuat.IsClose(backFromScaledAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, AxisAngleQuatRoundtripTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to axis-angle representation.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
// Convert the axis-angle back into a quaternion and compare the original quaternion with the one after the conversion.
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axis, angle);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareAxisAngleConversionTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to scaled axis-angle representation.
const AZ::Vector3 scaledAxisAngle = testQuat.ConvertToScaledAxisAngle();
// Convert test quaternion to axis-angle representation and scale it manually.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
// Compare the scaled result to the version from the helper that directly converts it to scaled axis-angle.
AZ::Vector3 scaledResult = axis*angle;
EXPECT_TRUE(scaledResult.IsClose(scaledAxisAngle, 1e-5f));
}
TEST_P(QuaternionScaledAxisAngleConversionFixture, CompareScaledAxisAngleConversionTests)
{
const AZ::Quaternion testQuat = GetAbs(GetParam());
// Convert test quaternion to axis-angle representation and scale it manually.
AZ::Vector3 axis;
float angle;
testQuat.ConvertToAxisAngle(axis, angle);
AZ::Vector3 scaledResult = axis*angle;
// Special case handling for identity rotation.
AZ::Vector3 axisFromScaledResult = scaledResult.GetNormalized();
float angleFromScaledResult = scaledResult.GetLength();
if (AZ::IsClose(angleFromScaledResult, 0.0f))
{
axisFromScaledResult = AZ::Vector3::CreateAxisY();
}
const AZ::Quaternion backFromAxisAngle = AZ::Quaternion::CreateFromAxisAngle(axisFromScaledResult, angleFromScaledResult);
EXPECT_TRUE(testQuat.IsClose(backFromAxisAngle, 1e-6f));
}
INSTANTIATE_TEST_CASE_P(MATH_Quaternion, QuaternionScaledAxisAngleConversionFixture, ::testing::ValuesIn(RotationRepresentationConversionTestQuats));
}