Merge remote-tracking branch 'upstream/main' into LYN-2726-ProjectRoot
This commit is contained in:
@@ -23,15 +23,11 @@ endif()
|
||||
|
||||
include(cmake/Version.cmake)
|
||||
|
||||
set(INSTALLED_ENGINE TRUE)
|
||||
|
||||
if(NOT PROJECT_NAME)
|
||||
project(O3DE
|
||||
LANGUAGES C CXX
|
||||
VERSION ${LY_VERSION_STRING}
|
||||
)
|
||||
|
||||
set(INSTALLED_ENGINE FALSE)
|
||||
endif()
|
||||
|
||||
include(cmake/Initialize.cmake)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Math/Crc.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <Range.h>
|
||||
#include <AnimKey.h>
|
||||
@@ -914,9 +915,18 @@ struct IAnimStringTable
|
||||
*/
|
||||
struct IAnimSequence
|
||||
{
|
||||
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}")
|
||||
AZ_RTTI(IAnimSequence, "{A60F95F5-5A4A-47DB-B3BB-525BBC0BC8DB}");
|
||||
AZ_CLASS_ALLOCATOR(IAnimSequence, AZ::SystemAllocator, 0);
|
||||
|
||||
static const int kSequenceVersion = 4;
|
||||
static const int kSequenceVersion = 5;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<IAnimSequence>();
|
||||
}
|
||||
}
|
||||
|
||||
//! Flags used for SetFlags(),GetFlags(),SetParentFlags(),GetParentFlags() methods.
|
||||
enum EAnimSequenceFlags
|
||||
|
||||
@@ -274,6 +274,10 @@ void PerInstanceConstantBufferPool::SetConstantBuffer(SRendItem* renderItem)
|
||||
deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex);
|
||||
deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledIndirectConstantBuffer[indirectId], eConstantBufferShaderSlot_SPIIndex);
|
||||
#else
|
||||
AZ::u32 itemIndex = directId % SPI_NUM_INSTS_PER_CB;
|
||||
AZ::u32 first[1] = {itemIndex * static_cast<AZ::u32>(sizeof(HLSL_PerInstanceConstantBuffer))};
|
||||
AZ::u32 count[1] = {static_cast<AZ::u32>(sizeof(HLSL_PerInstanceConstantBuffer))};
|
||||
|
||||
deviceManager.BindConstantBuffer(eHWSC_Vertex, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]);
|
||||
deviceManager.BindConstantBuffer(eHWSC_Pixel, m_PooledConstantBuffer[bufferIndex], eConstantBufferShaderSlot_SPI, first[0], count[0]);
|
||||
#endif
|
||||
|
||||
@@ -755,6 +755,7 @@ lSysUpdate:
|
||||
buffer_handle_t nVB = ~0u;
|
||||
# if BUFFER_ENABLE_DIRECT_ACCESS && !defined(NULL_RENDERER)
|
||||
nVB = MS->m_nID;
|
||||
int nFrame = gRenDev->m_RP.m_TI[gRenDev->m_RP.m_nFillThreadID].m_nFrameUpdateID;
|
||||
if ((nVB != ~0u && (MS->m_nFrameCreate != nFrame || MS->m_nElements != m_nVerts)) || !CRenderer::CV_r_buffer_enable_lockless_updates)
|
||||
# endif
|
||||
goto lSysCreate;
|
||||
|
||||
@@ -926,6 +926,8 @@ namespace AZ
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations)
|
||||
|
||||
@@ -167,14 +167,14 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector3& source)
|
||||
Vector2::Vector2(const Vector3& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector2::Vector2(const Vector4& source)
|
||||
Vector2::Vector2(const Vector4& source)
|
||||
: m_x(source.GetX())
|
||||
, m_y(source.GetY())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AZ::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AZ::PC:
|
||||
return "PC";
|
||||
case AZ::ES3:
|
||||
return "Android";
|
||||
case AZ::IOS:
|
||||
return "iOS";
|
||||
case AZ::OSX:
|
||||
return "Mac";
|
||||
case AZ::PROVO:
|
||||
return "Provo";
|
||||
case AZ::SALEM:
|
||||
return "Salem";
|
||||
case AZ::JASPER:
|
||||
return "Jasper";
|
||||
case AZ::SERVER:
|
||||
return "Server";
|
||||
case AZ::ALL:
|
||||
case AZ::ALL_CLIENT:
|
||||
case AZ::NumPlatformIds:
|
||||
case AZ::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if (checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
inline namespace PlatformDefaults
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string < (AssetPlatformFixedString{}.max_size() + 1)* PlatformId::NumPlatformIds > ;
|
||||
|
||||
const char* PlatformIdToPalFolder(PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
}
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <AzCore/JSON/pointer.h>
|
||||
#include <AzCore/JSON/prettywriter.h>
|
||||
#include <AzCore/JSON/writer.h>
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
@@ -525,9 +526,10 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
// and if that's missing just get "assets".
|
||||
constexpr char platformName[] = AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER;
|
||||
|
||||
SettingsRegistryInterface::FixedValueString assetPlatform;
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
|
||||
AZStd::string_view assetPlatformKey(buffer);
|
||||
// Use the platform codename to retrieve the default asset platform value
|
||||
SettingsRegistryInterface::FixedValueString assetPlatform = AZ::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
||||
if (!registry.Get(assetPlatform, assetPlatformKey))
|
||||
{
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
|
||||
|
||||
@@ -607,6 +607,8 @@ set(FILES
|
||||
Utils/Utils.h
|
||||
Script/lua/lua.h
|
||||
Memory/HeapSchema.cpp
|
||||
PlatformId/PlatformDefaults.h
|
||||
PlatformId/PlatformDefaults.cpp
|
||||
PlatformId/PlatformId.h
|
||||
PlatformId/PlatformId.cpp
|
||||
Socket/AzSocket_fwd.h
|
||||
|
||||
@@ -105,8 +105,6 @@ namespace AzFramework
|
||||
virtual bool SetDrawInFrontMode(bool bOn) { (void)bOn; return false; }
|
||||
virtual AZ::u32 GetState() { return 0; }
|
||||
virtual AZ::u32 SetState(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual AZ::u32 SetStateFlag(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual AZ::u32 ClearStateFlag(AZ::u32 state) { (void)state; return 0; }
|
||||
virtual void PushMatrix(const AZ::Transform& tm) { (void)tm; }
|
||||
virtual void PopMatrix() {}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Color.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
using FontId = uint32_t;
|
||||
static constexpr FontId InvalidFontId = 0xffffffffu;
|
||||
|
||||
enum class TextHorizontalAlignment : uint16_t
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Center
|
||||
};
|
||||
|
||||
enum class TextVerticalAlignment : uint16_t
|
||||
{
|
||||
Top,
|
||||
Bottom,
|
||||
Center,
|
||||
};
|
||||
|
||||
//! Standard parameters for drawing text on screen
|
||||
struct TextDrawParameters
|
||||
{
|
||||
ViewportId m_drawViewportId = InvalidViewportId; //! Viewport to draw into
|
||||
AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d.
|
||||
AZ::Color m_color = AZ::Colors::White; //! Color to draw the text
|
||||
AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale
|
||||
TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment
|
||||
TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment
|
||||
bool m_monospace = false; //! disable character proportional spacing
|
||||
bool m_depthTest = false; //! Test character against the depth buffer
|
||||
bool m_virtual800x600ScreenSize = true; //! Text placement and size are scaled relative to a virtual 800x600 resolution
|
||||
bool m_scaleWithWindow = false; //! Font gets bigger as the window gets bigger
|
||||
bool m_multiline = true; //! text respects ascii newline characters
|
||||
};
|
||||
|
||||
class FontDrawInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FontDrawInterface, "{545A7C14-CB3E-4A5B-B435-13EA606708EE}");
|
||||
|
||||
FontDrawInterface() = default;
|
||||
virtual ~FontDrawInterface() = default;
|
||||
|
||||
virtual void DrawScreenAlignedText2d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
virtual void DrawScreenAlignedText3d(
|
||||
const TextDrawParameters& params,
|
||||
const AZStd::string_view& string) = 0;
|
||||
};
|
||||
|
||||
class FontQueryInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FontQueryInterface, "{4BDD8520-EBC1-4680-B25E-421BDF31750F}");
|
||||
|
||||
FontQueryInterface() = default;
|
||||
virtual ~FontQueryInterface() = default;
|
||||
|
||||
FontId GetFontId(const AZStd::string_view& fontName) const {return FontId(AZ::Crc32(fontName));}
|
||||
virtual FontDrawInterface* GetFontDrawInterface(FontId) const = 0;
|
||||
virtual FontDrawInterface* GetDefaultFontDrawInterface() const = 0;
|
||||
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -1,338 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient };
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform)
|
||||
{
|
||||
#ifdef IOS
|
||||
#define AZ_REDEFINE_IOS_AT_END IOS
|
||||
#undef IOS
|
||||
#endif
|
||||
switch (platform)
|
||||
{
|
||||
case AzFramework::PC:
|
||||
return "PC";
|
||||
case AzFramework::ES3:
|
||||
return "Android";
|
||||
case AzFramework::IOS:
|
||||
return "iOS";
|
||||
case AzFramework::OSX:
|
||||
return "Mac";
|
||||
case AzFramework::PROVO:
|
||||
return "Provo";
|
||||
case AzFramework::SALEM:
|
||||
return "Salem";
|
||||
case AzFramework::JASPER:
|
||||
return "Jasper";
|
||||
case AzFramework::SERVER:
|
||||
return "Server";
|
||||
case AzFramework::ALL:
|
||||
case AzFramework::ALL_CLIENT:
|
||||
case AzFramework::NumPlatformIds:
|
||||
case AzFramework::Invalid:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef AZ_REDEFINE_IOS_AT_END
|
||||
#define IOS AZ_REDEFINE_IOS_AT_END
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform)
|
||||
{
|
||||
if (osPlatform == PlatformCodeNameWindows || osPlatform == PlatformCodeNameLinux)
|
||||
{
|
||||
return PlatformPC;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameMac)
|
||||
{
|
||||
return PlatformOSX;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameAndroid)
|
||||
{
|
||||
return PlatformES3;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameiOS)
|
||||
{
|
||||
return PlatformIOS;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameProvo)
|
||||
{
|
||||
return PlatformProvo;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameSalem)
|
||||
{
|
||||
return PlatformSalem;
|
||||
}
|
||||
else if (osPlatform == PlatformCodeNameJasper)
|
||||
{
|
||||
return PlatformJasper;
|
||||
}
|
||||
|
||||
AZ_Error("PlatformDefault", false, R"(Supplied OS platform "%.*s" does not have a corresponding default asset platform)",
|
||||
aznumeric_cast<int>(osPlatform.size()), osPlatform.data());
|
||||
return "";
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagFromPlatformIndex(PlatformId platformIndex)
|
||||
{
|
||||
if (platformIndex < 0 || platformIndex > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatforms(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platforms;
|
||||
for (int platformNum = 0; platformNum < PlatformId::NumPlatformIds; ++platformNum)
|
||||
{
|
||||
const bool isAllPlatforms = PlatformId::ALL == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE);
|
||||
|
||||
const bool isAllClientPlatforms = PlatformId::ALL_CLIENT == static_cast<PlatformId>(platformNum)
|
||||
&& ((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE);
|
||||
|
||||
if (isAllPlatforms || isAllClientPlatforms
|
||||
|| (platformFlags & static_cast<PlatformFlags>(1 << platformNum)) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platforms.push_back(PlatformNames[platformNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatforms(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndices(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> platformIndices;
|
||||
for (int i = 0; i < PlatformId::NumPlatformIds; i++)
|
||||
{
|
||||
PlatformId index = static_cast<PlatformId>(i);
|
||||
if ((GetPlatformFlagFromPlatformIndex(index) & platformFlags) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
platformIndices.emplace_back(index);
|
||||
}
|
||||
}
|
||||
return platformIndices;
|
||||
}
|
||||
|
||||
AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> PlatformHelper::GetPlatformIndicesInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
return GetPlatformIndices(GetPlatformFlagsInterpreted(platformFlags));
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlag(AZStd::string_view platform)
|
||||
{
|
||||
int platformIndex = GetPlatformIndexFromName(platform);
|
||||
if (platformIndex == PlatformId::Invalid)
|
||||
{
|
||||
AZ_Error("PlatformDefault", false, "Invalid Platform ( %.*s ).\n", static_cast<int>(platform.length()), platform.data());
|
||||
return PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
if(platformIndex == PlatformId::ALL)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if (platformIndex == PlatformId::ALL_CLIENT)
|
||||
{
|
||||
return PlatformFlags::Platform_ALL_CLIENT;
|
||||
}
|
||||
|
||||
return static_cast<PlatformFlags>(1 << platformIndex);
|
||||
}
|
||||
|
||||
const char* PlatformHelper::GetPlatformName(PlatformId platform)
|
||||
{
|
||||
if (platform < 0 || platform > PlatformId::NumPlatformIds)
|
||||
{
|
||||
return "invalid";
|
||||
}
|
||||
return PlatformNames[platform];
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformId)
|
||||
{
|
||||
PlatformId platform = GetPlatformIdFromName(platformId);
|
||||
AZ_Assert(platform != PlatformId::Invalid, "Unsupported Platform ID: %.*s", static_cast<int>(platformId.length()), platformId.data());
|
||||
AppendPlatformCodeNames(platformCodes, platform);
|
||||
}
|
||||
|
||||
void PlatformHelper::AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId)
|
||||
{
|
||||
// The IOS SDK has a macro that defines IOS as 1 which causes the enum below to be incorrectly converted to "PlatformId::1".
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
// To reduce work the Asset Processor groups assets that can be shared between hardware platforms together. For this
|
||||
// reason "PC" can for instance cover both the Windows and Linux platforms and "IOS" can cover AppleTV and iOS.
|
||||
switch (platformId)
|
||||
{
|
||||
case PlatformId::PC:
|
||||
platformCodes.emplace_back(PlatformCodeNameWindows);
|
||||
platformCodes.emplace_back(PlatformCodeNameLinux);
|
||||
break;
|
||||
case PlatformId::ES3:
|
||||
platformCodes.emplace_back(PlatformCodeNameAndroid);
|
||||
break;
|
||||
case PlatformId::IOS:
|
||||
platformCodes.emplace_back(PlatformCodeNameiOS);
|
||||
break;
|
||||
case PlatformId::OSX:
|
||||
platformCodes.emplace_back(PlatformCodeNameMac);
|
||||
break;
|
||||
case PlatformId::PROVO:
|
||||
platformCodes.emplace_back(PlatformCodeNameProvo);
|
||||
break;
|
||||
case PlatformId::SALEM:
|
||||
platformCodes.emplace_back(PlatformCodeNameSalem);
|
||||
break;
|
||||
case PlatformId::JASPER:
|
||||
platformCodes.emplace_back(PlatformCodeNameJasper);
|
||||
break;
|
||||
case PlatformId::SERVER:
|
||||
// Server is not a hardware platform
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported Platform ID: %i", platformId);
|
||||
break;
|
||||
}
|
||||
#pragma pop_macro("IOS")
|
||||
}
|
||||
|
||||
int PlatformHelper::GetPlatformIndexFromName(AZStd::string_view platformName)
|
||||
{
|
||||
for (int idx = 0; idx < PlatformId::NumPlatformIds; idx++)
|
||||
{
|
||||
if (platformName == PlatformNames[idx])
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return PlatformId::Invalid;
|
||||
}
|
||||
|
||||
PlatformId PlatformHelper::GetPlatformIdFromName(AZStd::string_view platformName)
|
||||
{
|
||||
return aznumeric_caster(GetPlatformIndexFromName(platformName));
|
||||
}
|
||||
|
||||
AssetPlatformCombinedString PlatformHelper::GetCommaSeparatedPlatformList(PlatformFlags platformFlags)
|
||||
{
|
||||
AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> platformNames = GetPlatforms(platformFlags);
|
||||
AssetPlatformCombinedString platformsString;
|
||||
AZ::StringFunc::Join(platformsString, platformNames.begin(), platformNames.end(), ", ");
|
||||
return platformsString;
|
||||
}
|
||||
|
||||
PlatformFlags PlatformHelper::GetPlatformFlagsInterpreted(PlatformFlags platformFlags)
|
||||
{
|
||||
PlatformFlags returnFlags = PlatformFlags::Platform_NONE;
|
||||
|
||||
if((platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if((platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE)
|
||||
{
|
||||
for (int i = 0; i < NumPlatforms; ++i)
|
||||
{
|
||||
auto platformId = static_cast<PlatformId>(i);
|
||||
|
||||
if (platformId != PlatformId::ALL && platformId != PlatformId::ALL_CLIENT && platformId != PlatformId::SERVER)
|
||||
{
|
||||
returnFlags |= GetPlatformFlagFromPlatformIndex(platformId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFlags = platformFlags;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
bool PlatformHelper::IsSpecialPlatform(PlatformFlags platformFlags)
|
||||
{
|
||||
return (platformFlags & PlatformFlags::Platform_ALL) != PlatformFlags::Platform_NONE
|
||||
|| (platformFlags & PlatformFlags::Platform_ALL_CLIENT) != PlatformFlags::Platform_NONE;
|
||||
}
|
||||
|
||||
bool HasFlagHelper(PlatformFlags flags, PlatformFlags checkPlatform)
|
||||
{
|
||||
return (flags & checkPlatform) == checkPlatform;
|
||||
}
|
||||
|
||||
|
||||
bool PlatformHelper::HasPlatformFlag(PlatformFlags flags, PlatformId checkPlatform)
|
||||
{
|
||||
// If checkPlatform contains any kind of invalid id, just exit out here
|
||||
if(checkPlatform == PlatformId::Invalid || checkPlatform == NumPlatforms)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ALL_CLIENT + SERVER = ALL
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT | PlatformFlags::Platform_SERVER))
|
||||
{
|
||||
flags = PlatformFlags::Platform_ALL;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL))
|
||||
{
|
||||
// It doesn't matter what checkPlatform is set to in this case, just return true
|
||||
return true;
|
||||
}
|
||||
|
||||
if(HasFlagHelper(flags, PlatformFlags::Platform_ALL_CLIENT))
|
||||
{
|
||||
return checkPlatform != PlatformId::SERVER;
|
||||
}
|
||||
|
||||
return HasFlagHelper(flags, GetPlatformFlagFromPlatformIndex(checkPlatform));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,144 +12,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
// On IOS builds IOS will be defined and interfere with the below enums
|
||||
#pragma push_macro("IOS")
|
||||
#undef IOS
|
||||
#include <AzCore/PlatformId/PlatformDefaults.h>
|
||||
|
||||
// As the Platform defaults is needed within AzCore,
|
||||
// those structures have been moved to AzCore and brought into
|
||||
// The AzFramework namespace for backwards compatibility
|
||||
namespace AzFramework
|
||||
{
|
||||
constexpr char PlatformPC[] = "pc";
|
||||
constexpr char PlatformES3[] = "es3";
|
||||
constexpr char PlatformIOS[] = "ios";
|
||||
constexpr char PlatformOSX[] = "osx_gl";
|
||||
constexpr char PlatformProvo[] = "provo";
|
||||
constexpr char PlatformSalem[] = "salem";
|
||||
constexpr char PlatformJasper[] = "jasper";
|
||||
constexpr char PlatformServer[] = "server";
|
||||
|
||||
constexpr char PlatformCodeNameWindows[] = "Windows";
|
||||
constexpr char PlatformCodeNameLinux[] = "Linux";
|
||||
constexpr char PlatformCodeNameAndroid[] = "Android";
|
||||
constexpr char PlatformCodeNameiOS[] = "iOS";
|
||||
constexpr char PlatformCodeNameMac[] = "Mac";
|
||||
constexpr char PlatformCodeNameProvo[] = "Provo";
|
||||
constexpr char PlatformCodeNameSalem[] = "Salem";
|
||||
constexpr char PlatformCodeNameJasper[] = "Jasper";
|
||||
constexpr char PlatformAll[] = "all";
|
||||
constexpr char PlatformAllClient[] = "all_client";
|
||||
|
||||
// Used for the capacity of a fixed vector to store the code names of platforms
|
||||
// The value needs to be higher than the number of unique OS platforms that are supported(at this time 8)
|
||||
constexpr size_t MaxPlatformCodeNames = 16;
|
||||
|
||||
//! This platform enum have platform values in sequence and can also be used to get the platform count.
|
||||
AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int,
|
||||
(Invalid, -1),
|
||||
PC,
|
||||
ES3,
|
||||
IOS,
|
||||
OSX,
|
||||
PROVO,
|
||||
SALEM,
|
||||
JASPER,
|
||||
SERVER, // Corresponds to the customer's flavor of "server" which could be windows, ubuntu, etc
|
||||
ALL,
|
||||
ALL_CLIENT,
|
||||
|
||||
// Add new platforms above this
|
||||
NumPlatformIds
|
||||
);
|
||||
constexpr int NumClientPlatforms = 7;
|
||||
constexpr int NumPlatforms = NumClientPlatforms + 1; // 1 "Server" platform currently
|
||||
enum class PlatformFlags : AZ::u32
|
||||
{
|
||||
Platform_NONE = 0x00,
|
||||
Platform_PC = 1 << PlatformId::PC,
|
||||
Platform_ES3 = 1 << PlatformId::ES3,
|
||||
Platform_IOS = 1 << PlatformId::IOS,
|
||||
Platform_OSX = 1 << PlatformId::OSX,
|
||||
Platform_PROVO = 1 << PlatformId::PROVO,
|
||||
Platform_SALEM = 1 << PlatformId::SALEM,
|
||||
Platform_JASPER = 1 << PlatformId::JASPER,
|
||||
Platform_SERVER = 1 << PlatformId::SERVER,
|
||||
|
||||
// A special platform that will always correspond to all platforms, even if new ones are added
|
||||
Platform_ALL = 1ULL << 30,
|
||||
|
||||
// A special platform that will always correspond to all non-server platforms, even if new ones are added
|
||||
Platform_ALL_CLIENT = 1ULL << 31,
|
||||
|
||||
AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER,
|
||||
};
|
||||
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags);
|
||||
|
||||
// 32 characters should be more than enough to store a platform name
|
||||
using AssetPlatformFixedString = AZStd::fixed_string<32>;
|
||||
// Fixed string which can store a comma separated list of platforms names
|
||||
// Additional byte is added to take into account the comma
|
||||
using AssetPlatformCombinedString = AZStd::fixed_string<(AssetPlatformFixedString{}.max_size() + 1) * PlatformId::NumPlatformIds>;
|
||||
|
||||
const char* PlatformIdToPalFolder(AzFramework::PlatformId platform);
|
||||
|
||||
const char* OSPlatformToDefaultAssetPlatform(AZStd::string_view osPlatform);
|
||||
|
||||
//! Platform Helper is an utility class that can be used to retrieve platform related information
|
||||
class PlatformHelper
|
||||
{
|
||||
public:
|
||||
|
||||
//! Given a platformIndex returns the platform name
|
||||
static const char* GetPlatformName(PlatformId platform);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, AZStd::string_view platformName);
|
||||
|
||||
//! Converts the platform name to the platform code names as defined in AZ_TRAIT_OS_PLATFORM_CODENAME.
|
||||
static void AppendPlatformCodeNames(AZStd::fixed_vector<AZStd::string_view, MaxPlatformCodeNames>& platformCodes, PlatformId platformId);
|
||||
|
||||
//! Given a platform name returns a platform index.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static int GetPlatformIndexFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platform name returns a platform id.
|
||||
//! If the platform is not found, the method returns -1.
|
||||
static PlatformId GetPlatformIdFromName(AZStd::string_view platformName);
|
||||
|
||||
//! Given a platformIndex returns the platformFlags
|
||||
static PlatformFlags GetPlatformFlagFromPlatformIndex(PlatformId platform);
|
||||
|
||||
//! Given a platformFlags returns all the platform identifiers that are set.
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatforms(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags returns all the platform identifiers that are set, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<AZStd::string_view, PlatformId::NumPlatformIds> GetPlatformsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platformFlags return a list of PlatformId indices
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndices(PlatformFlags platformFlags);
|
||||
//! Given a platformFlags return a list of PlatformId indices, with special flags interpreted. Do not use the result for saving
|
||||
static AZStd::fixed_vector<PlatformId, PlatformId::NumPlatformIds> GetPlatformIndicesInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Given a platform identifier returns its corresponding platform flag.
|
||||
static PlatformFlags GetPlatformFlag(AZStd::string_view platform);
|
||||
|
||||
//! Given any platformFlags returns a string listing the input platforms
|
||||
static AssetPlatformCombinedString GetCommaSeparatedPlatformList(PlatformFlags platformFlags);
|
||||
|
||||
//! If platformFlags contains any special flags, they are removed and replaced with the normal flags they represent
|
||||
static PlatformFlags GetPlatformFlagsInterpreted(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags contains any special flags
|
||||
static bool IsSpecialPlatform(PlatformFlags platformFlags);
|
||||
|
||||
//! Returns true if platformFlags has checkPlatform flag set.
|
||||
static bool HasPlatformFlag(PlatformFlags platformFlags, PlatformId checkPlatform);
|
||||
};
|
||||
using namespace AZ::PlatformDefaults;
|
||||
}
|
||||
|
||||
#pragma pop_macro("IOS")
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -133,6 +134,18 @@ namespace AzFramework
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
inline ScreenPoint ScreenPointFromNDC(const AZ::Vector3& screenNDC, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
return ScreenPoint(
|
||||
aznumeric_caster(std::round(screenNDC.GetX() * viewportSize.GetX())),
|
||||
aznumeric_caster(std::round((1.0f - screenNDC.GetY()) * viewportSize.GetY())));
|
||||
}
|
||||
|
||||
inline AZ::Vector2 NDCFromScreenPoint(const ScreenPoint& screenPoint, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
return AZ::Vector2(aznumeric_cast<float>(screenPoint.m_x), viewportSize.GetY() - aznumeric_cast<float>(screenPoint.m_y)) / viewportSize;
|
||||
}
|
||||
|
||||
//! Return an AZ::Vector2 from a ScreenPoint.
|
||||
inline AZ::Vector2 Vector2FromScreenPoint(const ScreenPoint& screenPoint)
|
||||
{
|
||||
|
||||
@@ -101,20 +101,25 @@ namespace AzFramework
|
||||
cameraState.m_nearClip, cameraState.m_farClip);
|
||||
}
|
||||
|
||||
ScreenPoint WorldToScreen(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection,
|
||||
const AZ::Vector2& viewportSize)
|
||||
AZ::Vector3 WorldToScreenNDC(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection)
|
||||
{
|
||||
// transform the world space position to clip space
|
||||
const auto clipSpacePosition = cameraProjection * cameraView * AZ::Vector3ToVector4(worldPosition, 1.0f);
|
||||
// transform the clip space position to ndc space (perspective divide)
|
||||
const auto ndcPosition = clipSpacePosition / clipSpacePosition.GetW();
|
||||
// transform ndc space from <-1,1> to <0, 1> range
|
||||
const auto ndcNormalizedPosition = (AZ::Vector4ToVector2(ndcPosition) + AZ::Vector2::CreateOne()) * 0.5f;
|
||||
return (AZ::Vector4ToVector3(ndcPosition) + AZ::Vector3::CreateOne()) * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
ScreenPoint WorldToScreen(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection,
|
||||
const AZ::Vector2& viewportSize)
|
||||
{
|
||||
const auto ndcNormalizedPosition = WorldToScreenNDC(worldPosition, cameraView, cameraProjection);
|
||||
// scale ndc position by screen dimensions to return screen position
|
||||
return ScreenPoint(
|
||||
aznumeric_caster(std::round(ndcNormalizedPosition.GetX() * viewportSize.GetX())),
|
||||
aznumeric_caster(std::round(viewportSize.GetY() - (ndcNormalizedPosition.GetY() * viewportSize.GetY()))));
|
||||
return ScreenPointFromNDC(ndcNormalizedPosition, viewportSize);
|
||||
}
|
||||
|
||||
ScreenPoint WorldToScreen(const AZ::Vector3& worldPosition, const CameraState& cameraState)
|
||||
@@ -127,12 +132,8 @@ namespace AzFramework
|
||||
const ScreenPoint& screenPosition, const AZ::Matrix4x4& inverseCameraView,
|
||||
const AZ::Matrix4x4& inverseCameraProjection, const AZ::Vector2& viewportSize)
|
||||
{
|
||||
const auto screenHeight = viewportSize.GetY();
|
||||
const auto flippedScreenPosition =
|
||||
AZ::Vector2(aznumeric_caster(screenPosition.m_x), aznumeric_caster(screenHeight - screenPosition.m_y));
|
||||
|
||||
// convert screen space coordinates to <-1,1> range
|
||||
const auto ndcPosition = (flippedScreenPosition / viewportSize) * 2.0f - AZ::Vector2::CreateOne();
|
||||
// convert screen space coordinates from <0, 1> to <-1,1> range
|
||||
const auto ndcPosition = NDCFromScreenPoint(screenPosition, viewportSize) * 2.0f - AZ::Vector2::CreateOne();
|
||||
|
||||
// transform ndc space position to clip space
|
||||
const auto clipSpacePosition = inverseCameraProjection * Vector2ToVector4(ndcPosition, -1.0f, 1.0f);
|
||||
|
||||
@@ -28,6 +28,11 @@ namespace AzFramework
|
||||
struct ScreenPoint;
|
||||
struct ViewportInfo;
|
||||
|
||||
//! Projects a position in world space to screen space normalized device coordinates for the given camera.
|
||||
AZ::Vector3 WorldToScreenNDC(
|
||||
const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection);
|
||||
|
||||
|
||||
//! Projects a position in world space to screen space for the given camera.
|
||||
ScreenPoint WorldToScreen(const AZ::Vector3& worldPosition, const CameraState& cameraState);
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@ set(FILES
|
||||
Components/NonUniformScaleComponent.cpp
|
||||
FileFunc/FileFunc.h
|
||||
FileFunc/FileFunc.cpp
|
||||
Font/FontInterface.h
|
||||
Gem/GemInfo.cpp
|
||||
Gem/GemInfo.h
|
||||
StringFunc/StringFunc.h
|
||||
@@ -316,7 +317,6 @@ set(FILES
|
||||
Terrain/TerrainDataRequestBus.h
|
||||
Terrain/TerrainDataRequestBus.cpp
|
||||
Platform/PlatformDefaults.h
|
||||
Platform/PlatformDefaults.cpp
|
||||
Windowing/WindowBus.h
|
||||
Windowing/NativeWindow.cpp
|
||||
Windowing/NativeWindow.h
|
||||
|
||||
@@ -80,6 +80,8 @@ namespace AzGameFramework
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
// Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry);
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList GameApplication::GetRequiredSystemComponents() const
|
||||
|
||||
+24
-21
@@ -53,7 +53,7 @@ namespace AzToolsFramework
|
||||
float, cl_viewportGizmoAxisLabelOffset, 1.15f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"The offset of the label for the viewport axis gizmo");
|
||||
AZ_CVAR(
|
||||
float, cl_viewportGizmoAxisLabelSize, 2.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
float, cl_viewportGizmoAxisLabelSize, 1.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"The size of each label for the viewport axis gizmo");
|
||||
AZ_CVAR(
|
||||
AZ::Vector2, cl_viewportGizmoAxisScreenPosition, AZ::Vector2(0.045f, 0.9f), nullptr,
|
||||
@@ -3434,19 +3434,22 @@ namespace AzToolsFramework
|
||||
const auto cameraProjection = AzFramework::CameraProjection(gizmoCameraState);
|
||||
|
||||
// screen space offset to move the 2d gizmo around
|
||||
const AZ::Vector3 screenPosition =
|
||||
(AZ::Vector2ToVector3(cl_viewportGizmoAxisScreenPosition) - AZ::Vector3(0.5f, 0.5f, 0.0f)) *
|
||||
AZ::Vector2ToVector3(gizmoCameraState.m_viewportSize);
|
||||
const AZ::Vector2 screenOffset = AZ::Vector2(cl_viewportGizmoAxisScreenPosition) - AZ::Vector2(0.5f, 0.5f);
|
||||
|
||||
// map from a position in world space (relative to the the gizmo camera near the origin) to a position in
|
||||
// screen space
|
||||
const auto calculateGizmoAxis =
|
||||
[&cameraView, &cameraProjection, &gizmoCameraState, &screenPosition]
|
||||
(const AZ::Vector3& position)
|
||||
[&cameraView, &cameraProjection, &screenOffset]
|
||||
(const AZ::Vector3& axis)
|
||||
{
|
||||
return AZ::Vector2ToVector3(AzFramework::Vector2FromScreenPoint(
|
||||
AzFramework::WorldToScreen(
|
||||
position, cameraView, cameraProjection, gizmoCameraState.m_viewportSize))) + screenPosition;
|
||||
auto result = AZ::Vector2(
|
||||
AzFramework::WorldToScreenNDC(
|
||||
axis,
|
||||
cameraView,
|
||||
cameraProjection)
|
||||
);
|
||||
result.SetY(1.0f - result.GetY());
|
||||
return result + screenOffset;
|
||||
};
|
||||
|
||||
// get all important axis positions in screen space
|
||||
@@ -3456,31 +3459,31 @@ namespace AzToolsFramework
|
||||
const auto gizmoEndAxisY = calculateGizmoAxis(-AZ::Vector3::CreateAxisY() * lineLength);
|
||||
const auto gizmoEndAxisZ = calculateGizmoAxis(-AZ::Vector3::CreateAxisZ() * lineLength);
|
||||
|
||||
const AZ::Vector3 gizmoAxisX = gizmoEndAxisX - gizmoStart;
|
||||
const AZ::Vector3 gizmoAxisY = gizmoEndAxisY - gizmoStart;
|
||||
const AZ::Vector3 gizmoAxisZ = gizmoEndAxisZ - gizmoStart;
|
||||
const AZ::Vector2 gizmoAxisX = gizmoEndAxisX - gizmoStart;
|
||||
const AZ::Vector2 gizmoAxisY = gizmoEndAxisY - gizmoStart;
|
||||
const AZ::Vector2 gizmoAxisZ = gizmoEndAxisZ - gizmoStart;
|
||||
|
||||
// draw the axes of the gizmo
|
||||
debugDisplay.SetLineWidth(cl_viewportGizmoAxisLineWidth);
|
||||
debugDisplay.SetColor(AZ::Colors::Red);
|
||||
debugDisplay.DrawLine(gizmoStart, gizmoEndAxisX);
|
||||
debugDisplay.DrawLine2d(gizmoStart, gizmoEndAxisX, 1.0f);
|
||||
debugDisplay.SetColor(AZ::Colors::Lime);
|
||||
debugDisplay.DrawLine(gizmoStart, gizmoEndAxisY);
|
||||
debugDisplay.DrawLine2d(gizmoStart, gizmoEndAxisY, 1.0f);
|
||||
debugDisplay.SetColor(AZ::Colors::Blue);
|
||||
debugDisplay.DrawLine(gizmoStart, gizmoEndAxisZ);
|
||||
debugDisplay.DrawLine2d(gizmoStart, gizmoEndAxisZ, 1.0f);
|
||||
debugDisplay.SetLineWidth(1.0f);
|
||||
|
||||
const float labelOffset = cl_viewportGizmoAxisLabelOffset;
|
||||
const auto labelOffsetX = gizmoStart + gizmoAxisX * labelOffset;
|
||||
const auto labelOffsetY = gizmoStart + gizmoAxisY * labelOffset;
|
||||
const auto labelOffsetZ = gizmoStart + gizmoAxisZ * labelOffset;
|
||||
const auto labelXScreenPosition = (gizmoStart + (gizmoAxisX * labelOffset)) * editorCameraState.m_viewportSize;
|
||||
const auto labelYScreenPosition = (gizmoStart + (gizmoAxisY * labelOffset)) * editorCameraState.m_viewportSize;
|
||||
const auto labelZScreenPosition = (gizmoStart + (gizmoAxisZ * labelOffset)) * editorCameraState.m_viewportSize;
|
||||
|
||||
// draw the label of of each axis for the gizmo
|
||||
const float labelSize = cl_viewportGizmoAxisLabelSize;
|
||||
debugDisplay.SetColor(AZ::Colors::White);
|
||||
debugDisplay.Draw2dTextLabel(labelOffsetX.GetX(), labelOffsetX.GetY(), labelSize, "X", true);
|
||||
debugDisplay.Draw2dTextLabel(labelOffsetY.GetX(), labelOffsetY.GetY(), labelSize, "Y", true);
|
||||
debugDisplay.Draw2dTextLabel(labelOffsetZ.GetX(), labelOffsetZ.GetY(), labelSize, "Z", true);
|
||||
debugDisplay.Draw2dTextLabel(labelXScreenPosition.GetX(), labelXScreenPosition.GetY(), labelSize, "X", true);
|
||||
debugDisplay.Draw2dTextLabel(labelYScreenPosition.GetX(), labelYScreenPosition.GetY(), labelSize, "Y", true);
|
||||
debugDisplay.Draw2dTextLabel(labelZScreenPosition.GetX(), labelZScreenPosition.GetY(), labelSize, "Z", true);
|
||||
}
|
||||
|
||||
void EditorTransformComponentSelection::DisplayViewportSelection2d(
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace UnitTest
|
||||
{
|
||||
assets[idx] = AssetId(AZ::Uuid::CreateRandom(), 0);
|
||||
AZ::Data::AssetInfo info;
|
||||
info.m_relativePath = AZStd::string::format("Asset%d.txt", idx);
|
||||
info.m_relativePath = AZStd::string::format("asset%d.txt", idx);
|
||||
m_assetsPath[idx] = info.m_relativePath;
|
||||
info.m_assetId = assets[idx];
|
||||
m_assetRegistry->RegisterAsset(assets[idx], info);
|
||||
@@ -623,7 +623,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("Asset%d.txt", fileIndex);
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex);
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
}
|
||||
@@ -654,7 +654,7 @@ namespace UnitTest
|
||||
EXPECT_TRUE(Search(assetList1, assets[fileIndex]));
|
||||
if (m_fileStreams[0][fileIndex].Open(m_assetsPathFull[0][fileIndex].c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary | AZ::IO::OpenMode::ModeCreatePath))
|
||||
{
|
||||
AZStd::string fileContent = AZStd::string::format("Asset%d.txt", fileIndex + 1);// changing file content
|
||||
AZStd::string fileContent = AZStd::string::format("asset%d.txt", fileIndex + 1);// changing file content
|
||||
m_fileStreams[0][fileIndex].Write(fileContent.size(), fileContent.c_str());
|
||||
m_fileStreams[0][fileIndex].Close();
|
||||
}
|
||||
@@ -987,7 +987,7 @@ namespace UnitTest
|
||||
|
||||
m_assetSeedManager->AddSeedAsset(assets[0], AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset0.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset0.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 0);
|
||||
}
|
||||
@@ -1003,7 +1003,7 @@ namespace UnitTest
|
||||
|
||||
m_assetSeedManager->AddSeedAsset(assets[0], AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset0.txt", AzFramework::PlatformFlags::Platform_PC);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset0.txt", AzFramework::PlatformFlags::Platform_PC);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 1);
|
||||
}
|
||||
@@ -1017,7 +1017,7 @@ namespace UnitTest
|
||||
|
||||
EXPECT_EQ(seedList.size(), 1);
|
||||
|
||||
m_assetSeedManager->RemoveSeedAsset("Asset1.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
m_assetSeedManager->RemoveSeedAsset("asset1.txt", AzFramework::PlatformFlags::Platform_PC | AzFramework::PlatformFlags::Platform_OSX);
|
||||
const AzFramework::AssetSeedList& secondSeedList = m_assetSeedManager->GetAssetSeedList();
|
||||
EXPECT_EQ(secondSeedList.size(), 1);
|
||||
}
|
||||
|
||||
@@ -1617,11 +1617,6 @@ void EditorViewportWidget::keyPressEvent(QKeyEvent* event)
|
||||
// because we want the movement to be butter smooth.
|
||||
if (!event->isAutoRepeat())
|
||||
{
|
||||
if (m_keyDown.isEmpty())
|
||||
{
|
||||
grabKeyboard();
|
||||
}
|
||||
|
||||
m_keyDown.insert(event->key());
|
||||
}
|
||||
|
||||
|
||||
@@ -1245,28 +1245,6 @@ uint32 DisplayContext::SetState(uint32 state)
|
||||
return old;
|
||||
}
|
||||
|
||||
//! Set a new render state flags.
|
||||
//! @param returns previous render state.
|
||||
uint32 DisplayContext::SetStateFlag(uint32 state)
|
||||
{
|
||||
uint32 old = m_renderState;
|
||||
m_renderState |= state;
|
||||
m_renderState = pRenderAuxGeom->GetRenderFlags().m_renderFlags;
|
||||
pRenderAuxGeom->SetRenderFlags(m_renderState);
|
||||
return old;
|
||||
}
|
||||
|
||||
//! Clear specified flags in render state.
|
||||
//! @param returns previous render state.
|
||||
uint32 DisplayContext::ClearStateFlag(uint32 state)
|
||||
{
|
||||
uint32 old = m_renderState;
|
||||
m_renderState &= ~state;
|
||||
m_renderState = pRenderAuxGeom->GetRenderFlags().m_renderFlags;
|
||||
pRenderAuxGeom->SetRenderFlags(m_renderState);
|
||||
return old;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void DisplayContext::DepthTestOff()
|
||||
{
|
||||
|
||||
@@ -2777,26 +2777,6 @@ AZ::u32 SandboxIntegrationManager::SetState(AZ::u32 state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
AZ::u32 SandboxIntegrationManager::SetStateFlag(AZ::u32 state)
|
||||
{
|
||||
if (m_dc)
|
||||
{
|
||||
return m_dc->SetStateFlag(state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AZ::u32 SandboxIntegrationManager::ClearStateFlag(AZ::u32 state)
|
||||
{
|
||||
if (m_dc)
|
||||
{
|
||||
return m_dc->ClearStateFlag(state);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SandboxIntegrationManager::PushMatrix(const AZ::Transform& tm)
|
||||
{
|
||||
if (m_dc)
|
||||
|
||||
@@ -268,8 +268,6 @@ private:
|
||||
bool SetDrawInFrontMode(bool bOn) override;
|
||||
AZ::u32 GetState() override;
|
||||
AZ::u32 SetState(AZ::u32 state) override;
|
||||
AZ::u32 SetStateFlag(AZ::u32 state) override;
|
||||
AZ::u32 ClearStateFlag(AZ::u32 state) override;
|
||||
void PushMatrix(const AZ::Transform& tm) override;
|
||||
void PopMatrix() override;
|
||||
|
||||
|
||||
+50
-19
@@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Authentication/AuthenticationProviderBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
@@ -28,74 +29,104 @@ namespace AWSClientAuth
|
||||
OnPasswordGrantMultiFactorConfirmSignInSuccess, OnPasswordGrantMultiFactorConfirmSignInFail,
|
||||
OnDeviceCodeGrantSignInSuccess, OnDeviceCodeGrantSignInFail,
|
||||
OnDeviceCodeGrantConfirmSignInSuccess, OnDeviceCodeGrantConfirmSignInFail,
|
||||
OnRefreshTokensSuccess, OnRefreshTokensFail,
|
||||
OnSignOut
|
||||
OnRefreshTokensSuccess, OnRefreshTokensFail
|
||||
);
|
||||
|
||||
void OnPasswordGrantSingleFactorSignInSuccess(const AuthenticationTokens& authenticationToken) override
|
||||
{
|
||||
Call(FN_OnPasswordGrantSingleFactorSignInSuccess, authenticationToken);
|
||||
AZ::TickBus::QueueFunction([authenticationToken, this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantSingleFactorSignInSuccess, authenticationToken);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPasswordGrantSingleFactorSignInFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnPasswordGrantSingleFactorSignInFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantSingleFactorSignInFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPasswordGrantMultiFactorSignInSuccess() override
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorSignInSuccess);
|
||||
AZ::TickBus::QueueFunction([this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorSignInSuccess);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPasswordGrantMultiFactorSignInFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorSignInFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorSignInFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPasswordGrantMultiFactorConfirmSignInSuccess(const AuthenticationTokens& authenticationToken) override
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorConfirmSignInSuccess, authenticationToken);
|
||||
AZ::TickBus::QueueFunction([authenticationToken, this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorConfirmSignInSuccess, authenticationToken);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPasswordGrantMultiFactorConfirmSignInFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorConfirmSignInFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnPasswordGrantMultiFactorConfirmSignInFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnDeviceCodeGrantSignInSuccess(
|
||||
const AZStd::string& userCode, const AZStd::string& verificationUrl, const int codeExpiresInSeconds) override
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantSignInSuccess, userCode, verificationUrl, codeExpiresInSeconds);
|
||||
AZ::TickBus::QueueFunction([userCode, verificationUrl, codeExpiresInSeconds, this]()
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantSignInSuccess, userCode, verificationUrl, codeExpiresInSeconds);
|
||||
});
|
||||
}
|
||||
|
||||
void OnDeviceCodeGrantSignInFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantSignInFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantSignInFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnDeviceCodeGrantConfirmSignInSuccess(const AuthenticationTokens& authenticationToken) override
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantConfirmSignInSuccess, authenticationToken);
|
||||
AZ::TickBus::QueueFunction([authenticationToken, this]()
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantConfirmSignInSuccess, authenticationToken);
|
||||
});
|
||||
}
|
||||
|
||||
void OnDeviceCodeGrantConfirmSignInFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantConfirmSignInFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnDeviceCodeGrantConfirmSignInFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnRefreshTokensSuccess(const AuthenticationTokens& authenticationToken) override
|
||||
{
|
||||
Call(FN_OnRefreshTokensSuccess, authenticationToken);
|
||||
AZ::TickBus::QueueFunction([authenticationToken, this]()
|
||||
{
|
||||
Call(FN_OnRefreshTokensSuccess, authenticationToken);
|
||||
});
|
||||
}
|
||||
|
||||
void OnRefreshTokensFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnRefreshTokensFail, error);
|
||||
}
|
||||
|
||||
void OnSignOut(const ProviderNameEnum& provideName) override
|
||||
{
|
||||
Call(FN_OnSignOut, provideName);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnRefreshTokensFail, error);
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
+20
-2
@@ -16,6 +16,7 @@
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <Authentication/AuthenticationProviderBus.h>
|
||||
#include <Authentication/AuthenticationProviderScriptCanvasBus.h>
|
||||
#include <Authentication/AuthenticationProviderInterface.h>
|
||||
#include <Authentication/AuthenticationTokens.h>
|
||||
|
||||
@@ -23,7 +24,8 @@ namespace AWSClientAuth
|
||||
{
|
||||
//! Manages various authentication provider implementations and implements AuthenticationProvider Request bus.
|
||||
class AuthenticationProviderManager
|
||||
: AuthenticationProviderRequestBus::Handler
|
||||
: public AuthenticationProviderRequestBus::Handler
|
||||
, public AuthenticationProviderScriptCanvasRequestBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AuthenticationProviderManager, "{45813BA5-9A46-4A2A-A923-C79CFBA0E63D}", IAuthenticationProviderRequests);
|
||||
@@ -43,6 +45,22 @@ namespace AWSClientAuth
|
||||
bool IsSignedIn(const ProviderNameEnum& providerName) override;
|
||||
bool SignOut(const ProviderNameEnum& providerName) override;
|
||||
AuthenticationTokens GetAuthenticationTokens(const ProviderNameEnum& providerName) override;
|
||||
|
||||
// AuthenticationProviderScriptCanvasRequest interface
|
||||
bool Initialize(const AZStd::vector<AZStd::string>& providerNames, const AZStd::string& settingsRegistryPath) override;
|
||||
void PasswordGrantSingleFactorSignInAsync(
|
||||
const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password) override;
|
||||
void PasswordGrantMultiFactorSignInAsync(
|
||||
const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password) override;
|
||||
void PasswordGrantMultiFactorConfirmSignInAsync(
|
||||
const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& confirmationCode) override;
|
||||
void DeviceCodeGrantSignInAsync(const AZStd::string& providerName) override;
|
||||
void DeviceCodeGrantConfirmSignInAsync(const AZStd::string& providerName) override;
|
||||
void RefreshTokensAsync(const AZStd::string& providerName) override;
|
||||
void GetTokensWithRefreshAsync(const AZStd::string& providerName) override;
|
||||
bool IsSignedIn(const AZStd::string& providerName) override;
|
||||
bool SignOut(const AZStd::string& providerName) override;
|
||||
AuthenticationTokens GetAuthenticationTokens(const AZStd::string& providerName) override;
|
||||
|
||||
virtual AZStd::unique_ptr<AuthenticationProviderInterface> CreateAuthenticationProviderObject(const ProviderNameEnum& providerName);
|
||||
AZStd::map<ProviderNameEnum, AZStd::unique_ptr<AuthenticationProviderInterface>> m_authenticationProvidersMap;
|
||||
@@ -50,9 +68,9 @@ namespace AWSClientAuth
|
||||
private:
|
||||
bool IsProviderInitialized(const ProviderNameEnum& providerName);
|
||||
void ResetProviders();
|
||||
ProviderNameEnum GetProviderNameEnum(AZStd::string name);
|
||||
|
||||
AZStd::shared_ptr<AZ::SettingsRegistryInterface> m_settingsRegistry;
|
||||
|
||||
};
|
||||
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <Authentication/AuthenticationTokens.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
//! Abstract class for authentication provider script canvas requests.
|
||||
//! Private class to allow provide names to be string type instead of an enum as behavior context does not work well with enum's.
|
||||
class IAuthenticationProviderScriptCanvasRequests
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(IAuthenticationProviderRequests, "{A8FD915F-9FF2-4BA3-8AA0-8CF7A94A323B}");
|
||||
|
||||
//! Parse the settings file for required settings for authentication providers. Instantiate and initialize authentication providers
|
||||
//! @param providerNames List of provider names to instantiate and initialize for Authentication.
|
||||
//! @param settingsRegistryPath Path for the settings registry file to use to configure providers.
|
||||
//! @return bool True: if all providers initialized successfully. False: If any provider fails initialization.
|
||||
virtual bool Initialize(const AZStd::vector<AZStd::string>& providerNames, const AZStd::string& settingsRegistryPath) = 0;
|
||||
|
||||
//! Checks if user is signed in.
|
||||
//! If access tokens are available and not expired.
|
||||
//! @param providerName Provider to check signed in for
|
||||
//! @return bool True if valid access token available, else False
|
||||
virtual bool IsSignedIn(const AZStd::string& providerName) = 0;
|
||||
|
||||
//! Get cached tokens from last last successful sign-in for the provider.
|
||||
//! @param providerName Provider to get authentication tokens
|
||||
//! @return AuthenticationTokens tokens from successful authentication.
|
||||
virtual AuthenticationTokens GetAuthenticationTokens(const AZStd::string& providerName) = 0;
|
||||
|
||||
// Below methods have corresponding notifications for success and failures.
|
||||
|
||||
//! Call sign in endpoint for provider password grant flow.
|
||||
//! @param providerName Provider to call sign in.
|
||||
//! @param username Username to use to for sign in.
|
||||
//! @param password Password to use to for sign in.
|
||||
virtual void PasswordGrantSingleFactorSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
|
||||
|
||||
//! Call sign in endpoint for provider password grant multi factor authentication flow.
|
||||
//! @param providerName Provider to call MFA sign in.
|
||||
//! @param username Username to use for MFA sign in.
|
||||
//! @param password Password to use for MFA sign in.
|
||||
virtual void PasswordGrantMultiFactorSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
|
||||
|
||||
//! Call confirm endpoint for provider password grant multi factor authentication flow .
|
||||
//! @param providerName Provider to call MFA confirm sign in.
|
||||
//! @param username Username to use for MFA confirm.
|
||||
//! @param confirmationCode Confirmation code (sent to email/text) to use for MFA confirm.
|
||||
virtual void PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& confirmationCode) = 0;
|
||||
|
||||
//! Call code-pair endpoint for provider device grant flow.
|
||||
//! @param providerName Provider to call device sign in.
|
||||
virtual void DeviceCodeGrantSignInAsync(const AZStd::string& providerName) = 0;
|
||||
|
||||
//! Call tokens endpoint for provider device grant flow.
|
||||
//! @param providerName Provider to call device confirm sign in.
|
||||
virtual void DeviceCodeGrantConfirmSignInAsync(const AZStd::string& providerName) = 0;
|
||||
|
||||
//! Call refresh endpoint for provider refresh grant flow.
|
||||
//! @param providerName Provider to call refresh tokens.
|
||||
virtual void RefreshTokensAsync(const AZStd::string& providerName) = 0;
|
||||
|
||||
//! Call refresh token if token not valid. If token valid, fires corresponding event.
|
||||
//! @param providerName Provider to get access token for.
|
||||
//! events: OnRefreshTokensSuccess, OnRefreshTokensFail
|
||||
virtual void GetTokensWithRefreshAsync(const AZStd::string& providerName) = 0;
|
||||
|
||||
//! Signs user out.
|
||||
//! Clears all cached tokens.
|
||||
//! @param providerName Provider to sign out.
|
||||
//! @return bool True: Successfully sign out.
|
||||
virtual bool SignOut(const AZStd::string& providerName) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
//! Authentication Request bus for different supported providers.
|
||||
class AuthenticationProviderScriptCanvasRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EBusTraits overrides
|
||||
using MutexType = AZ::NullMutex;
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
using AuthenticationProviderScriptCanvasRequestBus = AZ::EBus<IAuthenticationProviderScriptCanvasRequests, AuthenticationProviderScriptCanvasRequests>;
|
||||
|
||||
} // namespace AWSClientAuth
|
||||
@@ -15,6 +15,14 @@
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
constexpr char ProvideNameEnumStringNone[] = "None";
|
||||
constexpr char ProvideNameEnumStringAWSCognitoIDP[] = "AWSCognitoIDP";
|
||||
constexpr char ProvideNameEnumStringLoginWithAmazon[] = "LoginWithAmazon";
|
||||
constexpr char ProvideNameEnumStringGoogle[] = "Google";
|
||||
constexpr char ProvideNameEnumStringApple[] = "Apple";
|
||||
constexpr char ProvideNameEnumStringFacebook[] = "Facebook";
|
||||
constexpr char ProvideNameEnumStringTwitch[] = "Twitch";
|
||||
|
||||
//! Holds Login with Amazon provider serialized settings
|
||||
class LWAProviderSetting
|
||||
{
|
||||
|
||||
+9
-2
@@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Authorization/AWSCognitoAuthorizationBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
@@ -28,12 +29,18 @@ namespace AWSClientAuth
|
||||
|
||||
void OnRequestAWSCredentialsSuccess(const ClientAuthAWSCredentials& awsCredentials) override
|
||||
{
|
||||
Call(FN_OnRequestAWSCredentialsSuccess, awsCredentials);
|
||||
AZ::TickBus::QueueFunction([awsCredentials, this]()
|
||||
{
|
||||
Call(FN_OnRequestAWSCredentialsSuccess, awsCredentials);
|
||||
});
|
||||
}
|
||||
|
||||
void OnRequestAWSCredentialsFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnRequestAWSCredentialsFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]()
|
||||
{
|
||||
Call(FN_OnRequestAWSCredentialsFail, error);
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
+37
-12
@@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <UserManagement/AWSCognitoUserManagementBus.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
@@ -32,62 +33,86 @@ namespace AWSClientAuth
|
||||
|
||||
void OnEmailSignUpSuccess(const AZStd::string& uuid) override
|
||||
{
|
||||
Call(FN_OnEmailSignUpSuccess, uuid);
|
||||
AZ::TickBus::QueueFunction([uuid, this]() {
|
||||
Call(FN_OnEmailSignUpSuccess, uuid);
|
||||
});
|
||||
}
|
||||
|
||||
void OnEmailSignUpFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnEmailSignUpFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnEmailSignUpFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPhoneSignUpSuccess(const AZStd::string& uuid) override
|
||||
{
|
||||
Call(FN_OnPhoneSignUpSuccess, uuid);
|
||||
AZ::TickBus::QueueFunction([uuid, this]() {
|
||||
Call(FN_OnPhoneSignUpSuccess, uuid);
|
||||
});
|
||||
}
|
||||
|
||||
void OnPhoneSignUpFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnPhoneSignUpFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnPhoneSignUpFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnConfirmSignUpSuccess() override
|
||||
{
|
||||
Call(FN_OnConfirmSignUpSuccess);
|
||||
AZ::TickBus::QueueFunction([this]() {
|
||||
Call(FN_OnConfirmSignUpSuccess);
|
||||
});
|
||||
}
|
||||
|
||||
void OnConfirmSignUpFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnConfirmSignUpFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnConfirmSignUpFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnForgotPasswordSuccess() override
|
||||
{
|
||||
Call(FN_OnForgotPasswordSuccess);
|
||||
AZ::TickBus::QueueFunction([this]() {
|
||||
Call(FN_OnForgotPasswordSuccess);
|
||||
});
|
||||
}
|
||||
|
||||
void OnForgotPasswordFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnForgotPasswordFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnForgotPasswordFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnConfirmForgotPasswordSuccess() override
|
||||
{
|
||||
Call(FN_OnConfirmForgotPasswordSuccess);
|
||||
AZ::TickBus::QueueFunction([this]() {
|
||||
Call(FN_OnConfirmForgotPasswordSuccess);
|
||||
});
|
||||
}
|
||||
|
||||
void OnConfirmForgotPasswordFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnConfirmForgotPasswordFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnConfirmForgotPasswordFail, error);
|
||||
});
|
||||
}
|
||||
|
||||
void OnEnableMFASuccess() override
|
||||
{
|
||||
Call(FN_OnEnableMFASuccess);
|
||||
AZ::TickBus::QueueFunction([this]() {
|
||||
Call(FN_OnEnableMFASuccess);
|
||||
});
|
||||
}
|
||||
|
||||
void OnEnableMFAFail(const AZStd::string& error) override
|
||||
{
|
||||
Call(FN_OnEnableMFAFail, error);
|
||||
AZ::TickBus::QueueFunction([error, this]() {
|
||||
Call(FN_OnEnableMFAFail, error);
|
||||
});
|
||||
}
|
||||
};
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
//@ Abstract class for authentication provider requests.
|
||||
//! Abstract class for authentication provider requests.
|
||||
class IAuthenticationProviderRequests
|
||||
{
|
||||
public:
|
||||
@@ -35,32 +35,40 @@ namespace AWSClientAuth
|
||||
virtual bool IsSignedIn(const ProviderNameEnum& providerName) = 0;
|
||||
|
||||
//! Get cached tokens from last last successful sign-in for the provider.
|
||||
//! @param providerName Provider to get authentication tokens.
|
||||
//! @return AuthenticationTokens tokens from successful authentication.
|
||||
virtual AuthenticationTokens GetAuthenticationTokens(const ProviderNameEnum& providerName) = 0;
|
||||
|
||||
// Below methods have corresponding notifications for success and failures.
|
||||
|
||||
//! Call sign in endpoint for provider password grant flow.
|
||||
//! @param providerName Provider to call sign in.
|
||||
//! @param username Username to use to for sign in.
|
||||
//! @param password Password to use to for sign in.
|
||||
virtual void PasswordGrantSingleFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
|
||||
|
||||
//! Call sign in endpoint for provider password grant multi factor authentication flow.
|
||||
//! @param providerName Provider to call MFA sign in.
|
||||
//! @param username Username to use for MFA sign in.
|
||||
//! @param password Password to use for MFA sign in.
|
||||
virtual void PasswordGrantMultiFactorSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& password) = 0;
|
||||
|
||||
//! Call confirm endpoint for provider password grant multi factor authentication flow .
|
||||
//! @param providerName Provider to call MFA confirm sign in.
|
||||
//! @param username Username to use for MFA confirm.
|
||||
//! @param confirmationCode Confirmation code (sent to email/text) to use for MFA confirm.
|
||||
virtual void PasswordGrantMultiFactorConfirmSignInAsync(const ProviderNameEnum& providerName, const AZStd::string& username, const AZStd::string& confirmationCode) = 0;
|
||||
|
||||
//! Call code-pair endpoint for provider device grant flow.
|
||||
//! @param providerName Provider to call device sign in.
|
||||
virtual void DeviceCodeGrantSignInAsync(const ProviderNameEnum& providerName) = 0;
|
||||
|
||||
//! Call tokens endpoint for provider device grant flow.
|
||||
//! @param providerName Provider to call device confirm sign in.
|
||||
virtual void DeviceCodeGrantConfirmSignInAsync(const ProviderNameEnum& providerName) = 0;
|
||||
|
||||
//! Call refresh endpoint for provider refresh grant flow.
|
||||
//! @param providerName Provider to call refresh tokens.
|
||||
virtual void RefreshTokensAsync(const ProviderNameEnum& providerName) = 0;
|
||||
|
||||
//! Call refresh token if token not valid. If token valid, fires corresponding event.
|
||||
|
||||
@@ -11,20 +11,15 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Preprocessor/Enum.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/chrono/clocks.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
enum class ProviderNameEnum
|
||||
{
|
||||
None,
|
||||
AWSCognitoIDP,
|
||||
LoginWithAmazon,
|
||||
Google,
|
||||
Apple,
|
||||
Facebook
|
||||
};
|
||||
AZ_ENUM_CLASS(ProviderNameEnum, None, AWSCognitoIDP, LoginWithAmazon, Twitch, Google, Apple, Facebook);
|
||||
|
||||
//! Used to share authentication tokens to caller and to AWSCognitoAuthorizationController.
|
||||
class AuthenticationTokens
|
||||
@@ -55,6 +50,8 @@ namespace AWSClientAuth
|
||||
//! @return Expiration time in seconds.
|
||||
int GetTokensExpireTimeSeconds() const;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
private:
|
||||
int m_tokensExpireTimeSeconds = 0;
|
||||
AZStd::string m_accessToken;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
#include <aws/core/auth/AWSCredentialsProvider.h>
|
||||
@@ -24,6 +24,14 @@ namespace AWSClientAuth
|
||||
{
|
||||
public:
|
||||
AZ_TYPE_INFO(ClientAuthAWSCredentials, "{02FB32C4-B94E-4084-9049-3DF32F87BD76}");
|
||||
ClientAuthAWSCredentials() = default;
|
||||
ClientAuthAWSCredentials(const ClientAuthAWSCredentials& other)
|
||||
: m_accessKeyId(other.m_accessKeyId)
|
||||
, m_secretKey(other.m_secretKey)
|
||||
, m_sessionToken(other.m_sessionToken)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
ClientAuthAWSCredentials(const AZStd::string& accessKeyId, const AZStd::string& secretKey, const AZStd::string& sessionToken)
|
||||
{
|
||||
@@ -50,6 +58,32 @@ namespace AWSClientAuth
|
||||
return m_sessionToken;
|
||||
}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<ClientAuthAWSCredentials>()
|
||||
->Field("AWSAccessKeyId", &ClientAuthAWSCredentials::m_accessKeyId)
|
||||
->Field("AWSSecretKey", &ClientAuthAWSCredentials::m_secretKey)
|
||||
->Field("AWSSessionToken", &ClientAuthAWSCredentials::m_sessionToken);
|
||||
}
|
||||
|
||||
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<ClientAuthAWSCredentials>()
|
||||
->Attribute(AZ::Script::Attributes::Category, "AWSClientAuth")
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Constructor()
|
||||
->Constructor<const ClientAuthAWSCredentials&>()
|
||||
->Property("AWSAccessKeyId", BehaviorValueGetter(&ClientAuthAWSCredentials::m_accessKeyId), BehaviorValueSetter(&ClientAuthAWSCredentials::m_accessKeyId))
|
||||
->Property("AWSSecretKey", BehaviorValueGetter(&ClientAuthAWSCredentials::m_secretKey), BehaviorValueSetter(&ClientAuthAWSCredentials::m_secretKey))
|
||||
->Property("AWSSessionToken", BehaviorValueGetter(&ClientAuthAWSCredentials::m_sessionToken), BehaviorValueSetter(&ClientAuthAWSCredentials::m_sessionToken));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
AZStd::string m_accessKeyId;
|
||||
AZStd::string m_secretKey;
|
||||
|
||||
@@ -22,11 +22,12 @@ namespace AWSClientAuth
|
||||
public:
|
||||
AZ_TYPE_INFO(IAWSCognitoUserManagementRequests, "{A4C90F21-7056-4827-8C6B-401E6945697D}");
|
||||
|
||||
//! Initialize Cognito User pool.
|
||||
//! Initialize Cognito User pool using settings from resource mappings.
|
||||
//! @param settingsRegistryPath settingsRegistryPath Path for the settings registry file to use.
|
||||
virtual bool Initialize() = 0;
|
||||
|
||||
// Requests interface
|
||||
|
||||
//! Cognito user pool email sign up start.
|
||||
//! @param username User name to use for sign up.
|
||||
//! @param password Password to use for sign up.
|
||||
@@ -59,7 +60,7 @@ namespace AWSClientAuth
|
||||
virtual void EnableMFAAsync(const AZStd::string& accessToken) = 0;
|
||||
};
|
||||
|
||||
//! Manages various authentication provider implementations and implements AuthenticationProvider Request bus.
|
||||
//! Implements AWS Cognito user pool user management requests.
|
||||
class AWSCognitoUserManagementRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
|
||||
@@ -22,6 +22,11 @@
|
||||
#include <aws/cognito-identity/CognitoIdentityClient.h>
|
||||
#include <aws/cognito-idp/CognitoIdentityProviderClient.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(AWSClientAuth::ProviderNameEnum, "{FB34B23A-B249-47A2-B1F1-C05284B50CCC}");
|
||||
}
|
||||
|
||||
namespace AWSClientAuth
|
||||
{
|
||||
constexpr char SerializeComponentName[] = "AWSClientAuth";
|
||||
@@ -44,20 +49,35 @@ namespace AWSClientAuth
|
||||
AWSClientAuth::GoogleProviderSetting::Reflect(*serialize);
|
||||
}
|
||||
|
||||
AWSClientAuth::AuthenticationTokens::Reflect(context);
|
||||
AWSClientAuth::ClientAuthAWSCredentials::Reflect(context);
|
||||
|
||||
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->EBus<AuthenticationProviderRequestBus>("AuthenticationProviderRequestBus")
|
||||
behaviorContext->Enum<(int)ProviderNameEnum::None>("ProviderNameEnum_None")
|
||||
->Enum<(int)ProviderNameEnum::AWSCognitoIDP>("ProviderNameEnum_AWSCognitoIDP")
|
||||
->Enum<(int)ProviderNameEnum::LoginWithAmazon>("ProviderNameEnum_LoginWithAmazon")
|
||||
->Enum<(int)ProviderNameEnum::Google>("ProviderNameEnum_Google");
|
||||
|
||||
behaviorContext->EBus<AuthenticationProviderScriptCanvasRequestBus>("AuthenticationProviderRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
|
||||
->Event("Initialize", &AuthenticationProviderRequestBus::Events::Initialize)
|
||||
->Event("IsSignedIn", &AuthenticationProviderRequestBus::Events::IsSignedIn)
|
||||
->Event("GetAuthenticationTokens", &AuthenticationProviderRequestBus::Events::GetAuthenticationTokens)
|
||||
->Event("Initialize", &AuthenticationProviderScriptCanvasRequestBus::Events::Initialize)
|
||||
->Event("IsSignedIn", &AuthenticationProviderScriptCanvasRequestBus::Events::IsSignedIn)
|
||||
->Event("GetAuthenticationTokens", &AuthenticationProviderScriptCanvasRequestBus::Events::GetAuthenticationTokens)
|
||||
->Event(
|
||||
"PasswordGrantSingleFactorSignInAsync", &AuthenticationProviderRequestBus::Events::PasswordGrantSingleFactorSignInAsync)
|
||||
->Event("DeviceCodeGrantSignInAsync", &AuthenticationProviderRequestBus::Events::DeviceCodeGrantSignInAsync)
|
||||
->Event("DeviceCodeGrantConfirmSignInAsync", &AuthenticationProviderRequestBus::Events::DeviceCodeGrantConfirmSignInAsync)
|
||||
->Event("RefreshTokensAsync", &AuthenticationProviderRequestBus::Events::RefreshTokensAsync)
|
||||
->Event("GetTokensWithRefreshAsync", &AuthenticationProviderRequestBus::Events::GetTokensWithRefreshAsync)
|
||||
->Event("SignOut", &AuthenticationProviderRequestBus::Events::SignOut);
|
||||
"PasswordGrantSingleFactorSignInAsync",
|
||||
&AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantSingleFactorSignInAsync)
|
||||
->Event(
|
||||
"PasswordGrantMultiFactorSignInAsync",
|
||||
&AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantMultiFactorSignInAsync)
|
||||
->Event(
|
||||
"PasswordGrantMultiFactorConfirmSignInAsync",
|
||||
&AuthenticationProviderScriptCanvasRequestBus::Events::PasswordGrantMultiFactorConfirmSignInAsync)
|
||||
->Event("DeviceCodeGrantSignInAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::DeviceCodeGrantSignInAsync)
|
||||
->Event("DeviceCodeGrantConfirmSignInAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::DeviceCodeGrantConfirmSignInAsync)
|
||||
->Event("RefreshTokensAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::RefreshTokensAsync)
|
||||
->Event("GetTokensWithRefreshAsync", &AuthenticationProviderScriptCanvasRequestBus::Events::GetTokensWithRefreshAsync)
|
||||
->Event("SignOut", &AuthenticationProviderScriptCanvasRequestBus::Events::SignOut);
|
||||
|
||||
behaviorContext->EBus<AWSCognitoAuthorizationRequestBus>("AWSCognitoAuthorizationRequestBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
|
||||
@@ -77,11 +97,15 @@ namespace AWSClientAuth
|
||||
->Event("ConfirmForgotPasswordAsync", &AWSCognitoUserManagementRequestBus::Events::ConfirmForgotPasswordAsync)
|
||||
->Event("EnableMFAAsync", &AWSCognitoUserManagementRequestBus::Events::EnableMFAAsync);
|
||||
|
||||
|
||||
behaviorContext->EBus<AuthenticationProviderNotificationBus>("AuthenticationProviderNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
|
||||
->Handler<AuthenticationNotificationBusBehaviorHandler>();
|
||||
behaviorContext->EBus<AWSCognitoUserManagementNotificationBus>("AWSCognitoUserManagementNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
|
||||
->Handler<UserManagementNotificationBusBehaviorHandler>();
|
||||
behaviorContext->EBus<AWSCognitoAuthorizationNotificationBus>("AWSCognitoAuthorizationNotificationBus")
|
||||
->Attribute(AZ::Script::Attributes::Category, SerializeComponentName)
|
||||
->Handler<AWSCognitoAuthorizationNotificationBusBehaviorHandler>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace AWSClientAuth
|
||||
AZ_UNUSED(settingsRegistry);
|
||||
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
|
||||
m_cognitoAppClientId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoAppClientIdResourceMappingKey);
|
||||
AZ_Warning("AWSCognitoAuthenticationProvider", m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
|
||||
AZ_Warning("AWSCognitoAuthenticationProvider", !m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
|
||||
return !m_cognitoAppClientId.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Settings/SettingsRegistryImpl.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
|
||||
#include <Authentication/AuthenticationProviderTypes.h>
|
||||
#include <Authentication/AWSCognitoAuthenticationProvider.h>
|
||||
@@ -25,12 +26,14 @@ namespace AWSClientAuth
|
||||
{
|
||||
AZ::Interface<IAuthenticationProviderRequests>::Register(this);
|
||||
AuthenticationProviderRequestBus::Handler::BusConnect();
|
||||
AuthenticationProviderScriptCanvasRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
AuthenticationProviderManager::~AuthenticationProviderManager()
|
||||
{
|
||||
ResetProviders();
|
||||
m_settingsRegistry.reset();
|
||||
AuthenticationProviderScriptCanvasRequestBus::Handler::BusDisconnect();
|
||||
AuthenticationProviderRequestBus::Handler::BusDisconnect();
|
||||
AZ::Interface<IAuthenticationProviderRequests>::Unregister(this);
|
||||
}
|
||||
@@ -38,12 +41,19 @@ namespace AWSClientAuth
|
||||
bool AuthenticationProviderManager::Initialize(const AZStd::vector<ProviderNameEnum>& providerNames, const AZStd::string& settingsRegistryPath)
|
||||
{
|
||||
ResetProviders();
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO, "File IO is not initialized.");
|
||||
|
||||
m_settingsRegistry.reset();
|
||||
m_settingsRegistry = AZStd::make_shared<AZ::SettingsRegistryImpl>();
|
||||
|
||||
if (!m_settingsRegistry->MergeSettingsFile(settingsRegistryPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch))
|
||||
AZStd::array<char, AZ::IO::MaxPathLength> resolvedPath{};
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath(settingsRegistryPath.data(), resolvedPath.data(), resolvedPath.size());
|
||||
|
||||
|
||||
if (!m_settingsRegistry->MergeSettingsFile(resolvedPath.data(), AZ::SettingsRegistryInterface::Format::JsonMergePatch))
|
||||
{
|
||||
AZ_Error("AuthenticationProviderManager", true, "Error merging settings registry for path: %s", settingsRegistryPath.c_str());
|
||||
AZ_Error("AuthenticationProviderManager", true, "Error merging settings registry for path: %s", resolvedPath.data());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -112,6 +122,7 @@ namespace AWSClientAuth
|
||||
{
|
||||
AuthenticationProviderNotificationBus::Broadcast(&AuthenticationProviderNotifications::OnRefreshTokensFail
|
||||
, "Provider is not initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
AuthenticationTokens tokens = m_authenticationProvidersMap[providerName]->GetAuthenticationTokens();
|
||||
@@ -181,5 +192,77 @@ namespace AWSClientAuth
|
||||
}
|
||||
}
|
||||
|
||||
ProviderNameEnum AuthenticationProviderManager::GetProviderNameEnum(AZStd::string name)
|
||||
{
|
||||
auto enumValue = ProviderNameEnumNamespace::FromStringToProviderNameEnum(name);
|
||||
if (enumValue.has_value())
|
||||
{
|
||||
return enumValue.value();
|
||||
}
|
||||
AZ_Warning("AuthenticationProviderManager", true, "Incorrect string value for enum: %s", name.c_str());
|
||||
return ProviderNameEnum::None;
|
||||
}
|
||||
|
||||
bool AuthenticationProviderManager::Initialize(
|
||||
const AZStd::vector<AZStd::string>& providerNames, const AZStd::string& settingsRegistryPath)
|
||||
{
|
||||
AZStd::vector<ProviderNameEnum> providerNamesEnum;
|
||||
for (auto name : providerNames)
|
||||
{
|
||||
providerNamesEnum.push_back(GetProviderNameEnum(name));
|
||||
}
|
||||
return Initialize(providerNamesEnum, settingsRegistryPath);
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::PasswordGrantSingleFactorSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password)
|
||||
{
|
||||
PasswordGrantSingleFactorSignInAsync(GetProviderNameEnum(providerName), username, password);
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::PasswordGrantMultiFactorSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& password)
|
||||
{
|
||||
PasswordGrantMultiFactorSignInAsync(GetProviderNameEnum(providerName), username, password);
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::PasswordGrantMultiFactorConfirmSignInAsync(const AZStd::string& providerName, const AZStd::string& username, const AZStd::string& confirmationCode)
|
||||
{
|
||||
PasswordGrantMultiFactorConfirmSignInAsync(GetProviderNameEnum(providerName), username, confirmationCode);
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::DeviceCodeGrantSignInAsync(const AZStd::string& providerName)
|
||||
{
|
||||
DeviceCodeGrantSignInAsync(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::DeviceCodeGrantConfirmSignInAsync(const AZStd::string& providerName)
|
||||
{
|
||||
DeviceCodeGrantConfirmSignInAsync(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::RefreshTokensAsync(const AZStd::string& providerName)
|
||||
{
|
||||
RefreshTokensAsync(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
void AuthenticationProviderManager::GetTokensWithRefreshAsync(const AZStd::string& providerName)
|
||||
{
|
||||
GetTokensWithRefreshAsync(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
bool AuthenticationProviderManager::IsSignedIn(const AZStd::string& providerName)
|
||||
{
|
||||
return IsSignedIn(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
bool AuthenticationProviderManager::SignOut(const AZStd::string& providerName)
|
||||
{
|
||||
return SignOut(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
AuthenticationTokens AuthenticationProviderManager::GetAuthenticationTokens(const AZStd::string& providerName)
|
||||
{
|
||||
return GetAuthenticationTokens(GetProviderNameEnum(providerName));
|
||||
}
|
||||
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
|
||||
@@ -79,4 +79,30 @@ namespace AWSClientAuth
|
||||
{
|
||||
return m_tokensExpireTimeSeconds;
|
||||
}
|
||||
|
||||
void AuthenticationTokens::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AuthenticationTokens>()
|
||||
->Field("AccessToken", &AuthenticationTokens::m_accessToken)
|
||||
->Field("OpenIdToken", &AuthenticationTokens::m_openIdToken)
|
||||
->Field("RefreshToken", &AuthenticationTokens::m_refreshToken);
|
||||
}
|
||||
|
||||
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
|
||||
if (behaviorContext)
|
||||
{
|
||||
behaviorContext->Class<AuthenticationTokens>()
|
||||
->Attribute(AZ::Script::Attributes::Category, "AWSClientAuth")
|
||||
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Constructor()
|
||||
->Constructor<const AuthenticationTokens&>()
|
||||
->Property("AccessToken", BehaviorValueGetter(&AuthenticationTokens::m_accessToken), BehaviorValueSetter(&AuthenticationTokens::m_accessToken))
|
||||
->Property("OpenIdToken", BehaviorValueGetter(&AuthenticationTokens::m_openIdToken), BehaviorValueSetter(&AuthenticationTokens::m_accessToken))
|
||||
->Property("RefreshToken", BehaviorValueGetter(&AuthenticationTokens::m_refreshToken), BehaviorValueSetter(&AuthenticationTokens::m_accessToken));
|
||||
}
|
||||
}
|
||||
} // namespace AWSClientAuth
|
||||
|
||||
@@ -71,15 +71,15 @@ namespace AWSClientAuth
|
||||
|
||||
if (m_awsAccountId.empty() || m_cognitoIdentityPoolId.empty())
|
||||
{
|
||||
AZ_Warning("AWSCognitoUserManagementController", m_awsAccountId.empty(), "Missing AWS account id in resource mappings.");
|
||||
AZ_Warning("AWSCognitoUserManagementController", m_cognitoIdentityPoolId.empty(), "Missing Cognito Identity pool id in resource mappings.");
|
||||
AZ_Warning("AWSCognitoAuthorizationController", !m_awsAccountId.empty(), "Missing AWS account id not configured.");
|
||||
AZ_Warning("AWSCognitoAuthorizationController", !m_cognitoIdentityPoolId.empty(), "Missing Cognito Identity pool id in resource mappings.");
|
||||
return false;
|
||||
}
|
||||
|
||||
AZStd::string userPoolId;
|
||||
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
|
||||
userPoolId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoUserPoolIdResourceMappingKey);
|
||||
AZ_Warning("AWSCognitoUserManagementController", userPoolId.empty(), "Missing Cognito USer pool id in resource mappings. Cognito IDP authenticated identities will no work.");
|
||||
AZ_Warning("AWSCognitoAuthorizationController", !userPoolId.empty(), "Missing Cognito User pool id in resource mappings. Cognito IDP authenticated identities will no work.");
|
||||
|
||||
AZStd::string defaultRegion;
|
||||
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ namespace AWSClientAuth
|
||||
AWSCore::AWSResourceMappingRequestBus::BroadcastResult(
|
||||
m_cognitoAppClientId, &AWSCore::AWSResourceMappingRequests::GetResourceNameId, CognitoAppClientIdResourceMappingKey);
|
||||
AZ_Warning(
|
||||
"AWSCognitoUserManagementController", m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
|
||||
"AWSCognitoUserManagementController", !m_cognitoAppClientId.empty(), "Missing Cognito App Client Id from resource mappings. Calls to Cognito will fail.");
|
||||
return !m_cognitoAppClientId.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AWSClientAuthGemMock.h>
|
||||
#include <Authentication/AuthenticationProviderManager.h>
|
||||
|
||||
namespace AWSClientAuthUnitTest
|
||||
{
|
||||
class AuthenticationProviderManagerLocalMock
|
||||
: public AWSClientAuth::AuthenticationProviderManager
|
||||
{
|
||||
public:
|
||||
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantConfirmSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::GetAuthenticationTokens;
|
||||
using AWSClientAuth::AuthenticationProviderManager::GetTokensWithRefreshAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::Initialize;
|
||||
using AWSClientAuth::AuthenticationProviderManager::IsSignedIn;
|
||||
using AWSClientAuth::AuthenticationProviderManager::m_authenticationProvidersMap;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorConfirmSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantSingleFactorSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::RefreshTokensAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::SignOut;
|
||||
|
||||
AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface> CreateAuthenticationProviderObjectMock(
|
||||
const AWSClientAuth::ProviderNameEnum& providerName)
|
||||
{
|
||||
auto providerObject = AWSClientAuth::AuthenticationProviderManager::CreateAuthenticationProviderObject(providerName);
|
||||
providerObject.reset();
|
||||
return AZStd::make_unique<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>>();
|
||||
}
|
||||
|
||||
AuthenticationProviderManagerLocalMock()
|
||||
{
|
||||
ON_CALL(*this, CreateAuthenticationProviderObject(testing::_))
|
||||
.WillByDefault(testing::Invoke(this, &AuthenticationProviderManagerLocalMock::CreateAuthenticationProviderObjectMock));
|
||||
}
|
||||
|
||||
MOCK_METHOD1(
|
||||
CreateAuthenticationProviderObject,
|
||||
AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface>(const AWSClientAuth::ProviderNameEnum&));
|
||||
};
|
||||
} // namespace AWSClientAuthUnitTest
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <Authentication/AuthenticationProviderManager.h>
|
||||
#include <Authentication/AWSCognitoAuthenticationProvider.h>
|
||||
#include <Authentication/LWAAuthenticationProvider.h>
|
||||
#include <Authentication/AuthenticationTokens.h>
|
||||
#include <Authentication/AuthenticationProviderTypes.h>
|
||||
#include <AWSClientAuthGemMock.h>
|
||||
#include <Authentication/AuthenticationProviderManagerMock.h>
|
||||
|
||||
|
||||
class AuthenticationProviderManagerScriptCanvasTest
|
||||
: public AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::SetUp();
|
||||
|
||||
AWSClientAuth::LWAProviderSetting::Reflect(*m_serializeContext);
|
||||
AWSClientAuth::GoogleProviderSetting::Reflect(*m_serializeContext);
|
||||
|
||||
m_settingspath = AZStd::string::format("%s/%s/authenticationProvider.setreg",
|
||||
m_testFolder->c_str(), AZ::SettingsRegistryInterface::RegistryFolder);
|
||||
CreateTestFile("authenticationProvider.setreg"
|
||||
, R"({
|
||||
"AWS":
|
||||
{
|
||||
"LoginWithAmazon":
|
||||
{
|
||||
"AppClientId": "TestLWAClientId",
|
||||
"GrantType": "device_code",
|
||||
"Scope": "profile",
|
||||
"ResponseType": "device_code",
|
||||
"OAuthCodeURL": "https://api.amazon.com/auth/o2/create/codepair",
|
||||
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
|
||||
},
|
||||
"Google":
|
||||
{
|
||||
"AppClientId": "TestGoogleClientId",
|
||||
"ClientSecret": "123",
|
||||
"GrantType": "urn:ietf:params:oauth:grant-type:device_code",
|
||||
"Scope": "profile",
|
||||
"OAuthCodeURL": "https://oauth2.googleapis.com/device/code",
|
||||
"OAuthTokensURL": "https://oauth2.googleapis.com/token"
|
||||
}
|
||||
}
|
||||
})");
|
||||
|
||||
m_mockController = AZStd::make_unique<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderManagerLocalMock>>();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_mockController.reset();
|
||||
AWSClientAuthUnitTest::AWSClientAuthGemAllocatorFixture::TearDown();
|
||||
}
|
||||
|
||||
public:
|
||||
AZStd::unique_ptr<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderManagerLocalMock>> m_mockController;
|
||||
AZStd::string m_settingspath;
|
||||
AZStd::vector<AZStd::string> m_enabledProviderNames { AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP,
|
||||
AWSClientAuth::ProvideNameEnumStringLoginWithAmazon, AWSClientAuth::ProvideNameEnumStringGoogle};
|
||||
};
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, Initialize_Success)
|
||||
{
|
||||
ASSERT_TRUE(m_mockController->Initialize(m_enabledProviderNames, m_settingspath));
|
||||
ASSERT_TRUE(m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP] != nullptr);
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, PasswordGrantSingleFactorSignInAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, PasswordGrantSingleFactorSignInAsync(testing::_, testing::_)).Times(1);
|
||||
m_mockController->PasswordGrantSingleFactorSignInAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, PasswordGrantSingleFactorSignInAsync_Fail_NonConfiguredProviderError)
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
m_mockController->PasswordGrantSingleFactorSignInAsync(AWSClientAuth::ProvideNameEnumStringApple, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, PasswordGrantMultiFactorSignInAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, PasswordGrantMultiFactorSignInAsync(testing::_, testing::_)).Times(1);
|
||||
m_mockController->PasswordGrantMultiFactorSignInAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
|
||||
EXPECT_CALL(*lwaProviderMock, PasswordGrantMultiFactorSignInAsync(testing::_, testing::_)).Times(1);
|
||||
m_mockController->PasswordGrantMultiFactorSignInAsync(AWSClientAuth::ProvideNameEnumStringLoginWithAmazon, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, PasswordGrantMultiFactorConfirmSignInAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, PasswordGrantMultiFactorConfirmSignInAsync(testing::_, testing::_)).Times(1);
|
||||
m_mockController->PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
|
||||
EXPECT_CALL(*lwaProviderMock, PasswordGrantMultiFactorConfirmSignInAsync(testing::_, testing::_)).Times(1);
|
||||
m_mockController->PasswordGrantMultiFactorConfirmSignInAsync(AWSClientAuth::ProvideNameEnumStringLoginWithAmazon, AWSClientAuthUnitTest::TEST_USERNAME, AWSClientAuthUnitTest::TEST_PASSWORD);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, DeviceCodeGrantSignInAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, DeviceCodeGrantSignInAsync()).Times(1);
|
||||
m_mockController->DeviceCodeGrantSignInAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
EXPECT_CALL(*lwaProviderMock, DeviceCodeGrantSignInAsync()).Times(1);
|
||||
m_mockController->DeviceCodeGrantSignInAsync(AWSClientAuth::ProvideNameEnumStringLoginWithAmazon);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, DeviceCodeGrantConfirmSignInAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, DeviceCodeGrantConfirmSignInAsync()).Times(1);
|
||||
m_mockController->DeviceCodeGrantConfirmSignInAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
EXPECT_CALL(*lwaProviderMock, DeviceCodeGrantConfirmSignInAsync()).Times(1);
|
||||
m_mockController->DeviceCodeGrantConfirmSignInAsync(AWSClientAuth::ProvideNameEnumStringLoginWithAmazon);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, RefreshTokenAsync_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock> *lwaProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::LoginWithAmazon].get();
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(1);
|
||||
m_mockController->RefreshTokensAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
EXPECT_CALL(*lwaProviderMock, RefreshTokensAsync()).Times(1);
|
||||
m_mockController->RefreshTokensAsync(AWSClientAuth::ProvideNameEnumStringLoginWithAmazon);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, GetTokensWithRefreshAsync_ValidToken_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
|
||||
AWSClientAuth::AuthenticationTokens tokens(
|
||||
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
|
||||
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 600);
|
||||
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
|
||||
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(0);
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(1);
|
||||
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, GetTokensWithRefreshAsync_InvalidToken_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
AWSClientAuth::AuthenticationTokens tokens;
|
||||
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
|
||||
EXPECT_CALL(*cognitoProviderMock, RefreshTokensAsync()).Times(1);
|
||||
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, GetTokensWithRefreshAsync_NotInitializedProvider_Fail)
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
|
||||
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, GetTokens_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
|
||||
AWSClientAuth::AuthenticationTokens tokens(
|
||||
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
|
||||
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
|
||||
|
||||
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
|
||||
m_mockController->GetAuthenticationTokens(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, IsSignedIn_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* cognitoProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::AWSCognitoIDP].get();
|
||||
|
||||
AWSClientAuth::AuthenticationTokens tokens(
|
||||
AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN, AWSClientAuthUnitTest::TEST_TOKEN,
|
||||
AWSClientAuth::ProviderNameEnum::AWSCognitoIDP, 60);
|
||||
EXPECT_CALL(*cognitoProviderMock, GetAuthenticationTokens()).Times(1).WillOnce(testing::Return(tokens));
|
||||
m_mockController->IsSignedIn(AWSClientAuth::ProvideNameEnumStringAWSCognitoIDP);
|
||||
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, SignOut_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>* googleProviderMock = (testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>*)m_mockController->m_authenticationProvidersMap[AWSClientAuth::ProviderNameEnum::Google].get();
|
||||
|
||||
EXPECT_CALL(*googleProviderMock, SignOut()).Times(1);
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnSignOut(testing::_)).Times(1);
|
||||
m_mockController->SignOut(AWSClientAuth::ProvideNameEnumStringGoogle);
|
||||
|
||||
googleProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerScriptCanvasTest, Initialize_Fail_InvalidPath)
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
ASSERT_FALSE(m_mockController->Initialize(m_enabledProviderNames, ""));
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
+10
-38
@@ -10,8 +10,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
@@ -20,42 +18,7 @@
|
||||
#include <Authentication/LWAAuthenticationProvider.h>
|
||||
#include <Authentication/AuthenticationTokens.h>
|
||||
#include <AWSClientAuthGemMock.h>
|
||||
|
||||
namespace AWSClientAuthUnitTest
|
||||
{
|
||||
class AuthenticationProviderManagerLocalMock
|
||||
: public AWSClientAuth::AuthenticationProviderManager
|
||||
{
|
||||
public:
|
||||
using AWSClientAuth::AuthenticationProviderManager::m_authenticationProvidersMap;
|
||||
using AWSClientAuth::AuthenticationProviderManager::Initialize;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantSingleFactorSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::PasswordGrantMultiFactorConfirmSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::DeviceCodeGrantConfirmSignInAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::RefreshTokensAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::GetTokensWithRefreshAsync;
|
||||
using AWSClientAuth::AuthenticationProviderManager::GetAuthenticationTokens;
|
||||
using AWSClientAuth::AuthenticationProviderManager::SignOut;
|
||||
using AWSClientAuth::AuthenticationProviderManager::IsSignedIn;
|
||||
|
||||
AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface> CreateAuthenticationProviderObjectMock(const AWSClientAuth::ProviderNameEnum& providerName)
|
||||
{
|
||||
auto providerObject = AWSClientAuth::AuthenticationProviderManager::CreateAuthenticationProviderObject(providerName);
|
||||
providerObject.reset();
|
||||
return AZStd::make_unique<testing::NiceMock<AWSClientAuthUnitTest::AuthenticationProviderMock>>();
|
||||
}
|
||||
|
||||
AuthenticationProviderManagerLocalMock()
|
||||
{
|
||||
ON_CALL(*this, CreateAuthenticationProviderObject(testing::_)).WillByDefault(
|
||||
testing::Invoke(this, &AuthenticationProviderManagerLocalMock::CreateAuthenticationProviderObjectMock));
|
||||
}
|
||||
|
||||
MOCK_METHOD1(CreateAuthenticationProviderObject, AZStd::unique_ptr<AWSClientAuth::AuthenticationProviderInterface>(const AWSClientAuth::ProviderNameEnum&));
|
||||
};
|
||||
}
|
||||
#include <Authentication/AuthenticationProviderManagerMock.h>
|
||||
|
||||
|
||||
class AuthenticationProviderManagerTest
|
||||
@@ -239,6 +202,15 @@ TEST_F(AuthenticationProviderManagerTest, GetTokensWithRefreshAsync_InvalidToken
|
||||
cognitoProviderMock = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerTest, GetTokensWithRefreshAsync_NotInitializedProvider_Fail)
|
||||
{
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensSuccess(testing::_)).Times(0);
|
||||
EXPECT_CALL(m_authenticationProviderNotificationsBusMock, OnRefreshTokensFail(testing::_)).Times(1);
|
||||
m_mockController->GetTokensWithRefreshAsync(AWSClientAuth::ProviderNameEnum::AWSCognitoIDP);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
}
|
||||
|
||||
TEST_F(AuthenticationProviderManagerTest, GetTokens_Success)
|
||||
{
|
||||
m_mockController->Initialize(m_enabledProviderNames, m_settingspath);
|
||||
|
||||
@@ -20,6 +20,7 @@ set(FILES
|
||||
Include/Private/AWSClientAuthBus.h
|
||||
Include/Private/AWSClientAuthResourceMappingConstants.h
|
||||
Include/Private/Authentication/AuthenticationProviderTypes.h
|
||||
Include/Private/Authentication/AuthenticationProviderScriptCanvasBus.h
|
||||
Include/Private/Authentication/AuthenticationProviderManager.h
|
||||
Include/Private/Authentication/AuthenticationNotificationBusBehaviorHandler.h
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ set(FILES
|
||||
Tests/AWSClientAuthGemTest.cpp
|
||||
|
||||
Tests/AWSClientAuthSystemComponentTest.cpp
|
||||
Tests/Authentication/AuthenticationProviderManagerMock.h
|
||||
Tests/Authentication/AuthenticationProviderManagerTest.cpp
|
||||
Tests/Authentication/AuthenticationProviderManagerScriptCanvasBusTest.cpp
|
||||
Tests/Authentication/AWSCognitoAuthenticationProviderTest.cpp
|
||||
Tests/Authentication/LWAAuthenticationProviderTest.cpp
|
||||
Tests/Authentication/GoogleAuthenticationProviderTest.cpp
|
||||
|
||||
@@ -56,8 +56,7 @@ class CognitoIdentityPoolRole:
|
||||
# basic permissions
|
||||
stack_statement = iam.PolicyStatement(
|
||||
actions=[
|
||||
's3:Get*',
|
||||
's3:List*'
|
||||
's3:ListBuckets'
|
||||
],
|
||||
effect=iam.Effect.ALLOW,
|
||||
resources=[
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace AZ
|
||||
void AuxGeomDrawQueue::DrawQuad(
|
||||
float width,
|
||||
float height,
|
||||
const AZ::Transform& transform,
|
||||
const AZ::Matrix3x4& transform,
|
||||
const AZ::Color& color,
|
||||
DrawStyle style,
|
||||
DepthTest depthTest,
|
||||
@@ -302,8 +302,8 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
Transform noScaleTransform = transform;
|
||||
noScaleTransform.ExtractScale();
|
||||
AZ::Matrix3x4 noScaleTransform = transform;
|
||||
AZ::Vector3 scale = noScaleTransform.ExtractScale();
|
||||
|
||||
ShapeBufferEntry shape;
|
||||
shape.m_shapeType = ShapeType_Quad;
|
||||
@@ -311,9 +311,9 @@ namespace AZ
|
||||
shape.m_depthWrite = ConvertRPIDepthWriteFlag(depthWrite);
|
||||
shape.m_faceCullMode = ConvertRPIFaceCullFlag(faceCull);
|
||||
shape.m_color = color;
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromTransform(noScaleTransform);
|
||||
shape.m_rotationMatrix = Matrix3x3::CreateFromMatrix3x4(noScaleTransform);
|
||||
shape.m_position = transform.GetTranslation();
|
||||
shape.m_scale = transform.GetScale() * Vector3(width, 1.0f, height);
|
||||
shape.m_scale = scale * Vector3(width, 1.0f, height);
|
||||
shape.m_pointSize = m_pointSize;
|
||||
shape.m_viewProjOverrideIndex = viewProjOverrideIndex;
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace AZ
|
||||
void DrawTriangles(const AuxGeomDynamicIndexedDrawArguments& args, FaceCullMode faceCull = FaceCullMode::None) override;
|
||||
|
||||
// Fixed shape draws
|
||||
void DrawQuad(float width, float height, const AZ::Transform& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawQuad(float width, float height, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawSphere(const AZ::Vector3& center, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawDisk(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
void DrawCone(const AZ::Vector3& center, const AZ::Vector3& direction, float radius, float height, const AZ::Color& color, DrawStyle style, DepthTest depthTest, DepthWrite depthWrite, FaceCullMode faceCull, int32_t viewProjOverrideIndex) override;
|
||||
|
||||
@@ -131,8 +131,13 @@ namespace AZ
|
||||
AZ_Assert(m_blendedLut.m_lutImage != nullptr, "BlendColorGradingLutsPass unable to acquire LUT image");
|
||||
|
||||
AZ::RHI::AttachmentId imageAttachmentId = AZ::RHI::AttachmentId("BlendColorGradingLutImageAttachmentId");
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(imageAttachmentId, m_blendedLut.m_lutImage);
|
||||
AZ_Error("BlendColorGradingLutsPass", result == RHI::ResultCode::Success, "Failed to import compute buffer with error %d", result);
|
||||
|
||||
// import this attachment if it wasn't imported
|
||||
if (!frameGraph.GetAttachmentDatabase().IsAttachmentValid(imageAttachmentId))
|
||||
{
|
||||
[[maybe_unused]] RHI::ResultCode result = frameGraph.GetAttachmentDatabase().ImportImage(imageAttachmentId, m_blendedLut.m_lutImage);
|
||||
AZ_Error("BlendColorGradingLutsPass", result == RHI::ResultCode::Success, "Failed to import BlendColorGradingLutImageAttachmentId with error %d", result);
|
||||
}
|
||||
|
||||
RHI::ImageScopeAttachmentDescriptor desc;
|
||||
desc.m_attachmentId = imageAttachmentId;
|
||||
|
||||
@@ -16,6 +16,6 @@ namespace AZ
|
||||
{
|
||||
namespace RHI
|
||||
{
|
||||
bool Validation::s_isEnabled = BuildOptions::IsDebugBuild;
|
||||
bool Validation::s_isEnabled = BuildOptions::IsDebugBuild || BuildOptions::IsProfileBuild;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,6 +404,12 @@ namespace AZ
|
||||
Buffer& buffer = static_cast<Buffer&>(*bufferFrameAttachment.GetBuffer());
|
||||
RHI::BufferScopeAttachment* scopeAttachment = bufferFrameAttachment.GetFirstScopeAttachment();
|
||||
|
||||
if (scopeAttachment == nullptr)
|
||||
{
|
||||
AZ_WarningOnce("RHI", false, "Imported BufferFrameAttachment isn't used in any Scope");
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_TRANSITION_BARRIER transition;
|
||||
transition.pResource = buffer.GetMemoryView().GetMemory();
|
||||
transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
@@ -471,6 +477,12 @@ namespace AZ
|
||||
Image& image = static_cast<Image&>(*imageFrameAttachment.GetImage());
|
||||
RHI::ImageScopeAttachment* scopeAttachment = imageFrameAttachment.GetFirstScopeAttachment();
|
||||
|
||||
if (scopeAttachment == nullptr)
|
||||
{
|
||||
AZ_WarningOnce("RHI", false, "Imported ImageFrameAttachment isn't used in any Scope");
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_TRANSITION_BARRIER transition;
|
||||
transition.pResource = image.GetMemoryView().GetMemory();
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ namespace AZ
|
||||
//! @param depthWrite If depth writing should be enabled
|
||||
//! @param faceCull Which (if any) facing triangles should be culled
|
||||
//! @param viewProjOverrideIndex Which view projection override entry to use, -1 if unused
|
||||
virtual void DrawQuad(float width, float height, const AZ::Transform& transform, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
virtual void DrawQuad(float width, float height, const AZ::Matrix3x4& transform, const AZ::Color& color, DrawStyle style = DrawStyle::Shaded, DepthTest depthTest = DepthTest::On, DepthWrite depthWrite = DepthWrite::On, FaceCullMode faceCull = FaceCullMode::Back, int32_t viewProjOverrideIndex = -1) = 0;
|
||||
|
||||
//! Draw a sphere.
|
||||
//! @param center The center of the sphere.
|
||||
|
||||
@@ -16,6 +16,6 @@ namespace AZ
|
||||
{
|
||||
namespace RPI
|
||||
{
|
||||
bool Validation::s_isEnabled = RHI::BuildOptions::IsDebugBuild;
|
||||
bool Validation::s_isEnabled = RHI::BuildOptions::IsDebugBuild || RHI::BuildOptions::IsProfileBuild;
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -53,6 +53,9 @@ namespace MaterialEditor
|
||||
//! Modify camera's field of view
|
||||
//! @param value field of view in degrees
|
||||
virtual void SetFieldOfView(float value) = 0;
|
||||
|
||||
//! Check if camera is looking directly at a model
|
||||
virtual bool IsCameraCentered() const = 0;
|
||||
};
|
||||
|
||||
using MaterialEditorViewportInputControllerRequestBus = AZ::EBus<MaterialEditorViewportInputControllerRequests>;
|
||||
|
||||
@@ -76,11 +76,35 @@ namespace MaterialEditor
|
||||
void Behavior::TickInternal([[maybe_unused]] float x, [[maybe_unused]] float y, float z)
|
||||
{
|
||||
m_distanceToTarget = m_distanceToTarget - z;
|
||||
|
||||
bool isCameraCentered = false;
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
isCameraCentered,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::IsCameraCentered);
|
||||
|
||||
// if camera is looking at the model (locked to the model) we don't want to zoom past the model's center
|
||||
if (isCameraCentered)
|
||||
{
|
||||
m_distanceToTarget = AZ::GetMax(m_distanceToTarget, 0.0f);
|
||||
}
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Vector3 position = m_targetPosition -
|
||||
transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(m_distanceToTarget));
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTranslation, position);
|
||||
|
||||
// if camera is not locked to the model, move its focal point so we can free look
|
||||
if (!isCameraCentered)
|
||||
{
|
||||
m_targetPosition += transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(z));
|
||||
MaterialEditorViewportInputControllerRequestBus::Broadcast(
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::SetTargetPosition,
|
||||
m_targetPosition);
|
||||
MaterialEditorViewportInputControllerRequestBus::BroadcastResult(
|
||||
m_distanceToTarget,
|
||||
&MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget);
|
||||
}
|
||||
}
|
||||
|
||||
float Behavior::GetSensitivityX()
|
||||
|
||||
+13
@@ -96,6 +96,7 @@ namespace MaterialEditor
|
||||
void MaterialEditorViewportInputController::SetTargetPosition(const AZ::Vector3& targetPosition)
|
||||
{
|
||||
m_targetPosition = targetPosition;
|
||||
m_isCameraCentered = false;
|
||||
}
|
||||
|
||||
float MaterialEditorViewportInputController::GetDistanceToTarget() const
|
||||
@@ -246,6 +247,7 @@ namespace MaterialEditor
|
||||
cameraPosition = cameraRotation.TransformVector(cameraPosition);
|
||||
AZ::Transform cameraTransform = AZ::Transform::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition);
|
||||
AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTM, cameraTransform);
|
||||
m_isCameraCentered = true;
|
||||
|
||||
// reset model
|
||||
AZ::Transform modelTransform = AZ::Transform::CreateIdentity();
|
||||
@@ -258,6 +260,12 @@ namespace MaterialEditor
|
||||
AZ::RPI::ScenePtr scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene();
|
||||
auto skyBoxFeatureProcessorInterface = scene->GetFeatureProcessor<AZ::Render::SkyBoxFeatureProcessorInterface>();
|
||||
skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix);
|
||||
|
||||
if (m_behavior)
|
||||
{
|
||||
m_behavior->End();
|
||||
m_behavior->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::SetFieldOfView(float value)
|
||||
@@ -265,6 +273,11 @@ namespace MaterialEditor
|
||||
Camera::CameraRequestBus::Event(m_cameraEntityId, &Camera::CameraRequestBus::Events::SetFovDegrees, value);
|
||||
}
|
||||
|
||||
bool MaterialEditorViewportInputController::IsCameraCentered() const
|
||||
{
|
||||
return m_isCameraCentered;
|
||||
}
|
||||
|
||||
void MaterialEditorViewportInputController::CalculateExtents()
|
||||
{
|
||||
AZ::TransformBus::EventResult(m_modelCenter, m_targetEntityId, &AZ::TransformBus::Events::GetLocalTranslation);
|
||||
|
||||
+3
@@ -45,6 +45,7 @@ namespace MaterialEditor
|
||||
void GetExtents(float& distanceMin, float& distanceMax) const override;
|
||||
void Reset() override;
|
||||
void SetFieldOfView(float value) override;
|
||||
bool IsCameraCentered() const override;
|
||||
|
||||
// AzFramework::ViewportControllerInstance interface overrides...
|
||||
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
|
||||
@@ -95,6 +96,8 @@ namespace MaterialEditor
|
||||
float m_distanceMin = 1.0f;
|
||||
//! Maximum distance from camera to target
|
||||
float m_distanceMax = 10.0f;
|
||||
//! True if camera is centered on a model
|
||||
bool m_isCameraCentered = true;
|
||||
|
||||
static constexpr float MaxDistanceMultiplier = 2.5f;
|
||||
static constexpr float StartingDistanceMultiplier = 2.0f;
|
||||
|
||||
+1
-3
@@ -34,10 +34,8 @@ namespace MaterialEditor
|
||||
targetPosition);
|
||||
}
|
||||
|
||||
void PanCameraBehavior::TickInternal(float x, float y, float z)
|
||||
void PanCameraBehavior::TickInternal(float x, float y, [[maybe_unused]] float z)
|
||||
{
|
||||
Behavior::TickInternal(x, y, z);
|
||||
|
||||
AZ::Transform transform = AZ::Transform::CreateIdentity();
|
||||
AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM);
|
||||
AZ::Quaternion rotation = transform.GetRotation();
|
||||
|
||||
+21
-8
@@ -60,13 +60,17 @@ namespace MaterialEditor
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, enumerateCB, nullptr);
|
||||
|
||||
//Update the material type file info whenever the combo box selection changes
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, static_cast<void(QComboBox::*)(const int)>(&QComboBox::currentIndexChanged), m_ui->m_materialTypeComboBox, [this](int index) {
|
||||
QVariant data = m_ui->m_materialTypeComboBox->itemData(index);
|
||||
m_materialTypeFileInfo = QFileInfo(data.toString());
|
||||
});
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, static_cast<void (QComboBox::*)(const int)>(&QComboBox::currentIndexChanged), this, [this]() { UpdateMaterialTypeSelection(); });
|
||||
QObject::connect(m_ui->m_materialTypeComboBox, &QComboBox::currentTextChanged, this, [this]() { UpdateMaterialTypeSelection(); });
|
||||
|
||||
//Select StandardPBR by default but we will later data drive this with editor settings
|
||||
m_ui->m_materialTypeComboBox->setCurrentText("StandardPBR");
|
||||
// Select StandardPBR by default but we will later data drive this with editor settings
|
||||
const int index = m_ui->m_materialTypeComboBox->findText("StandardPBR");
|
||||
if (index >= 0)
|
||||
{
|
||||
m_ui->m_materialTypeComboBox->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
UpdateMaterialTypeSelection();
|
||||
}
|
||||
|
||||
void CreateMaterialDialog::InitMaterialFileSelection()
|
||||
@@ -88,15 +92,24 @@ namespace MaterialEditor
|
||||
m_materialFileInfo.absoluteFilePath(),
|
||||
QString("Material (*.material)"));
|
||||
|
||||
//Reject empty or invalid filenames which indicate user cancellation
|
||||
// Reject empty or invalid filenames which indicate user cancellation
|
||||
if (!fileInfo.absoluteFilePath().isEmpty())
|
||||
{
|
||||
m_materialFileInfo = fileInfo;
|
||||
m_ui->m_materialFilePicker->setText(m_materialFileInfo.fileName());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void CreateMaterialDialog::UpdateMaterialTypeSelection()
|
||||
{
|
||||
const int index = m_ui->m_materialTypeComboBox->currentIndex();
|
||||
if (index >= 0)
|
||||
{
|
||||
const QVariant itemData = m_ui->m_materialTypeComboBox->itemData(index);
|
||||
m_materialTypeFileInfo = QFileInfo(itemData.toString());
|
||||
}
|
||||
}
|
||||
} // namespace MaterialEditor
|
||||
|
||||
#include <Window/CreateMaterialDialog/moc_CreateMaterialDialog.cpp>
|
||||
|
||||
+1
@@ -36,5 +36,6 @@ namespace MaterialEditor
|
||||
QScopedPointer<Ui::CreateMaterialDialog> m_ui;
|
||||
void InitMaterialTypeSelection();
|
||||
void InitMaterialFileSelection();
|
||||
void UpdateMaterialTypeSelection();
|
||||
};
|
||||
} // namespace MaterialEditor
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace AZ
|
||||
bool m_showTimeline = false;
|
||||
|
||||
// Controls how often the timestamp data is refreshed
|
||||
RefreshType m_refreshType = RefreshType::OncePerSecond;
|
||||
RefreshType m_refreshType = RefreshType::Realtime;
|
||||
AZStd::sys_time_t m_lastUpdateTimeMicroSecond;
|
||||
|
||||
};
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
#include <Atom/RPI.Public/Scene.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Render
|
||||
@@ -725,7 +727,7 @@ namespace AZ
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Name: %s", passEntry->m_name.GetCStr());
|
||||
ImGui::Text("Path: %s", passEntry->m_path.GetCStr());
|
||||
ImGui::Text("Duration in ticks: %lu", passEntry->m_timestampResult.GetDurationInTicks());
|
||||
ImGui::Text("Duration in ticks: %" PRIu64, passEntry->m_timestampResult.GetDurationInTicks());
|
||||
ImGui::Text("Duration in microsecond: %.3f us", passEntry->m_timestampResult.GetDurationInNanoseconds()/1000.f);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
+1408
-895
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,10 @@ namespace AZ::AtomBridge
|
||||
AZ::RPI::AuxGeomDraw::DepthWrite m_depthWrite = AZ::RPI::AuxGeomDraw::DepthWrite::On;
|
||||
AZ::RPI::AuxGeomDraw::FaceCullMode m_faceCullMode = AZ::RPI::AuxGeomDraw::FaceCullMode::Back;
|
||||
int32_t m_viewProjOverrideIndex = -1; // will be used to implement SetDrawInFrontMode & 2D mode
|
||||
|
||||
// separate tracking for Cry only state
|
||||
bool m_drawInFront = false;
|
||||
bool m_2dMode = false;
|
||||
};
|
||||
|
||||
//! Utility class to collect line segments when the number of segments is known at compile time.
|
||||
@@ -77,6 +81,24 @@ namespace AZ::AtomBridge
|
||||
}
|
||||
}
|
||||
|
||||
void Draw2d(AZ::RPI::AuxGeomDrawPtr auxGeomDrawPtr, const RenderState& rendState) const
|
||||
{
|
||||
if (auxGeomDrawPtr && !m_points.empty())
|
||||
{
|
||||
AZ::RPI::AuxGeomDraw::AuxGeomDynamicDrawArguments drawArgs;
|
||||
drawArgs.m_verts = m_points.data();
|
||||
drawArgs.m_vertCount = aznumeric_cast<uint32_t>(m_points.size());
|
||||
drawArgs.m_colors = &rendState.m_color;
|
||||
drawArgs.m_colorCount = 1;
|
||||
drawArgs.m_size = rendState.m_lineWidth;
|
||||
drawArgs.m_opacityType = rendState.m_opacityType;
|
||||
drawArgs.m_depthTest = rendState.m_depthTest;
|
||||
drawArgs.m_depthWrite = rendState.m_depthWrite;
|
||||
drawArgs.m_viewProjectionOverrideIndex = auxGeomDrawPtr->GetOrAdd2DViewProjOverride();
|
||||
auxGeomDrawPtr->DrawLines( drawArgs );
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_points.clear();
|
||||
@@ -91,6 +113,7 @@ namespace AZ::AtomBridge
|
||||
SingleColorDynamicSizeLineHelper(int estimatedNumLineSegments);
|
||||
void AddLineSegment(const AZ::Vector3& lineStart, const AZ::Vector3& lineEnd);
|
||||
void Draw(AZ::RPI::AuxGeomDrawPtr auxGeomDrawPtr, const RenderState& rendState) const;
|
||||
void Draw2d(AZ::RPI::AuxGeomDrawPtr auxGeomDrawPtr, const RenderState& rendState) const;
|
||||
void Reset();
|
||||
|
||||
AZStd::vector<AZ::Vector3> m_points;
|
||||
@@ -119,9 +142,9 @@ namespace AZ::AtomBridge
|
||||
void SetColor(const AZ::Vector4& color) override;
|
||||
void SetAlpha(float a) override;
|
||||
void DrawQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) override;
|
||||
// void DrawQuad(float width, float height) overr
|
||||
// void DrawWireQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) override;
|
||||
// void DrawWireQuad(float width, float height) override;
|
||||
void DrawQuad(float width, float height) override;
|
||||
void DrawWireQuad(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4) override;
|
||||
void DrawWireQuad(float width, float height) override;
|
||||
void DrawQuadGradient(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3, const AZ::Vector3& p4, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) override;
|
||||
void DrawTri(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector3& p3) override;
|
||||
void DrawTriangles(const AZStd::vector<AZ::Vector3>& vertices, const AZ::Color& color) override;
|
||||
@@ -134,10 +157,10 @@ namespace AZ::AtomBridge
|
||||
void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2, const AZ::Vector4& col1, const AZ::Vector4& col2) override;
|
||||
void DrawLines(const AZStd::vector<AZ::Vector3>& lines, const AZ::Color& color) override;
|
||||
void DrawPolyLine(const AZ::Vector3* pnts, int numPoints, bool cycled = true) override;
|
||||
// void DrawWireQuad2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override;
|
||||
// void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override;
|
||||
// void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) override;
|
||||
// void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) override;
|
||||
void DrawWireQuad2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override;
|
||||
void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) override;
|
||||
void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) override;
|
||||
void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) override;
|
||||
void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis = 2) override;
|
||||
void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) override;
|
||||
void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) override;
|
||||
@@ -152,13 +175,13 @@ namespace AZ::AtomBridge
|
||||
void DrawBall(const AZ::Vector3& pos, float radius, bool drawShaded) override;
|
||||
void DrawDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) override;
|
||||
void DrawArrow(const AZ::Vector3& src, const AZ::Vector3& trg, float headScale = 1.0f, bool dualEndedArrow = false) override;
|
||||
// void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) override;
|
||||
// void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) override;
|
||||
// void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) override;
|
||||
void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) override;
|
||||
void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) override;
|
||||
void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) override;
|
||||
// unhandled on Atom - virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override;
|
||||
// void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) override;
|
||||
void SetLineWidth(float width) override;
|
||||
// bool IsVisible(const AZ::Aabb& bounds) override;
|
||||
bool IsVisible(const AZ::Aabb& bounds) override;
|
||||
// int SetFillMode(int nFillMode) override;
|
||||
float GetLineWidth() override;
|
||||
float GetAspectRatio() override;
|
||||
@@ -169,10 +192,8 @@ namespace AZ::AtomBridge
|
||||
void CullOff() override;
|
||||
void CullOn() override;
|
||||
bool SetDrawInFrontMode(bool on) override;
|
||||
// AZ::u32 GetState() override;
|
||||
// AZ::u32 SetState(AZ::u32 state) override;
|
||||
// AZ::u32 SetStateFlag(AZ::u32 state) override;
|
||||
// AZ::u32 ClearStateFlag(AZ::u32 state) override;
|
||||
AZ::u32 GetState() override;
|
||||
AZ::u32 SetState(AZ::u32 state) override;
|
||||
void PushMatrix(const AZ::Transform& tm) override;
|
||||
void PopMatrix() override;
|
||||
|
||||
@@ -226,6 +247,10 @@ namespace AZ::AtomBridge
|
||||
|
||||
void InitInternal(RPI::Scene* scene, AZ::RPI::ViewportContextPtr viewportContextPtr);
|
||||
|
||||
AZ::RPI::ViewportContextPtr GetViewportContext() const;
|
||||
|
||||
uint32_t ConvertRenderStateToCry() const;
|
||||
|
||||
RenderState m_rendState;
|
||||
|
||||
AZ::RPI::AuxGeomDrawPtr m_auxGeomPtr;
|
||||
|
||||
@@ -20,8 +20,14 @@
|
||||
#include <IXml.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/smart_ptr/weak_ptr.h>
|
||||
#include <AzCore/std/parallel/shared_mutex.h>
|
||||
#include <map>
|
||||
|
||||
#include <AzFramework/Font/FontInterface.h>
|
||||
#include <AzFramework/Scene/SceneSystemBus.h>
|
||||
|
||||
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class FFont;
|
||||
@@ -33,6 +39,8 @@ namespace AZ
|
||||
//! and manages their loading & saving together.
|
||||
class AtomFont
|
||||
: public ICryFont
|
||||
, public AzFramework::FontQueryInterface
|
||||
, public AzFramework::SceneSystemNotificationBus::Handler
|
||||
{
|
||||
friend class FFont;
|
||||
|
||||
@@ -79,16 +87,31 @@ namespace AZ
|
||||
void ReloadAllFonts() override;
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// FontQueryInterface implementation
|
||||
AzFramework::FontDrawInterface* GetFontDrawInterface(AzFramework::FontId fontId) const override;
|
||||
AzFramework::FontDrawInterface* GetDefaultFontDrawInterface() const override;
|
||||
|
||||
// SceneSystemNotificationBus handlers
|
||||
void SceneAboutToBeRemoved(AzFramework::Scene& scene) override;
|
||||
|
||||
|
||||
// Atom DynamicDraw interface management
|
||||
AZ::RHI::Ptr<AZ::RPI::DynamicDrawContext> GetOrCreateDynamicDrawForScene(AZ::RPI::Scene* scene);
|
||||
|
||||
|
||||
public:
|
||||
void UnregisterFont(const char* fontName);
|
||||
|
||||
private:
|
||||
typedef std::map<string, FFont*> FontMap;
|
||||
typedef FontMap::iterator FontMapItor;
|
||||
typedef FontMap::const_iterator FontMapConstItor;
|
||||
using FontMap = std::unordered_map<AzFramework::FontId, FFont*>;
|
||||
using FontMapItor = FontMap::iterator;
|
||||
using FontMapConstItor = FontMap::const_iterator;
|
||||
|
||||
typedef AZStd::map<AZStd::string, AZStd::weak_ptr<FontFamily>> FontFamilyMap;
|
||||
typedef AZStd::map<FontFamily*, FontFamilyMap::iterator> FontFamilyReverseLookupMap;
|
||||
using FontFamilyMap = AZStd::unordered_map<AZStd::string, AZStd::weak_ptr<FontFamily>>;
|
||||
using FontFamilyReverseLookupMap = AZStd::unordered_map<FontFamily*, FontFamilyMap::iterator>;
|
||||
|
||||
using SceneToDynamicDrawMap = AZStd::unordered_map<AZ::RPI::Scene*, AZ::RPI::Ptr<AZ::RPI::DynamicDrawContext>>;
|
||||
|
||||
private:
|
||||
//! Convenience method for loading fonts
|
||||
@@ -119,9 +142,13 @@ namespace AZ
|
||||
FontFamilyReverseLookupMap m_fontFamilyReverseLookup; //<! FontFamily pointer reverse-lookup for quick removal
|
||||
ISystem* m_system;
|
||||
|
||||
AzFramework::FontDrawInterface* m_defaultFontDrawInterface = nullptr;
|
||||
|
||||
int r_persistFontFamilies = 1; //!< Persist fonts for application lifetime to prevent unnecessary work; enabled by default.
|
||||
AZStd::vector<FontFamilyPtr> m_persistedFontFamilies; //!< Stores persisted fonts (if "persist font families" is enabled)
|
||||
|
||||
SceneToDynamicDrawMap m_sceneToDynamicDrawMap;
|
||||
AZStd::shared_mutex m_sceneToDynamicDrawMutex;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzFramework/Font/FontInterface.h>
|
||||
|
||||
#include <Atom/RHI.Reflect/Base.h>
|
||||
#include <Atom/RHI/StreamBufferView.h>
|
||||
@@ -57,6 +58,8 @@ namespace AZ
|
||||
void operator () (const AZStd::intrusive_refcount<AZStd::atomic_uint, FontDeleter>* ptr) const;
|
||||
};
|
||||
|
||||
using TextDrawContext = STextDrawContext;
|
||||
|
||||
//! FFont is the implementation of IFFont used to draw text with a particular font (e.g. Consolas Italic)
|
||||
//! FFont manages creation of a gpu texture to cache the font and generates draw commands that use that texture.
|
||||
//! FFont's are managed by AtomFont as either individual font instances or a font family
|
||||
@@ -64,12 +67,12 @@ namespace AZ
|
||||
class FFont
|
||||
: public IFFont
|
||||
, public AZStd::intrusive_refcount<AZStd::atomic_uint, FontDeleter>
|
||||
, public AzFramework::FontDrawInterface
|
||||
, private AZ::Render::Bootstrap::NotificationBus::Handler
|
||||
{
|
||||
using ref_count = AZStd::intrusive_refcount<AZStd::atomic_uint, FontDeleter>;
|
||||
friend FontDeleter;
|
||||
public:
|
||||
using TextDrawContext = STextDrawContext;
|
||||
//! Determines how characters of different sizes should be handled during render.
|
||||
enum class SizeBehavior
|
||||
{
|
||||
@@ -201,6 +204,14 @@ namespace AZ
|
||||
uint32_t GetFontTextureVersion() override;
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AzFramework::FontDrawInterface implementation
|
||||
void DrawScreenAlignedText2d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string) override;
|
||||
|
||||
void DrawScreenAlignedText3d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string) override;
|
||||
|
||||
public:
|
||||
FFont(AtomFont* atomFont, const char* fontName);
|
||||
@@ -220,8 +231,18 @@ namespace AZ
|
||||
bool InitCache();
|
||||
|
||||
void Prepare(const char* str, bool updateTexture, const AtomFont::GlyphSize& glyphSize = AtomFont::defaultGlyphSize);
|
||||
void DrawStringUInternal(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx);
|
||||
Vec2 GetTextSizeUInternal(const char* str, const bool asciiMultiLine, const TextDrawContext& ctx);
|
||||
void DrawStringUInternal(
|
||||
const RHI::Viewport& viewport,
|
||||
RPI::ViewportContext* viewportContext,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
const char* str,
|
||||
const bool asciiMultiLine,
|
||||
const TextDrawContext& ctx);
|
||||
Vec2 GetTextSizeUInternal(const RHI::Viewport& viewport, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx);
|
||||
Vec2 GetKerningInternal(const RHI::Viewport& viewport, uint32_t leftGlyph, uint32_t rightGlyph, const TextDrawContext& ctx) const;
|
||||
float GetBaselineInternal(const RHI::Viewport& viewport, const TextDrawContext& ctx) const;
|
||||
|
||||
// returns true if add operation was successful, false otherwise
|
||||
using AddFunction = AZStd::function<bool(const Vec3&, const Vec3&, const Vec3&, const Vec3&, const Vec2&, const Vec2&, const Vec2&, const Vec2&, uint32_t)>;
|
||||
@@ -229,6 +250,7 @@ namespace AZ
|
||||
//! This function is used by both DrawStringUInternal and WriteTextQuadsToBuffers
|
||||
//! To do this is takes a function pointer that implement the appropriate AddQuad behavior
|
||||
int CreateQuadsForText(
|
||||
const RHI::Viewport& viewport,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
@@ -247,16 +269,16 @@ namespace AZ
|
||||
float rcpCellWidth;
|
||||
};
|
||||
|
||||
TextScaleInfoInternal CalculateScaleInternal(const TextDrawContext& ctx) const;
|
||||
TextScaleInfoInternal CalculateScaleInternal(const RHI::Viewport& viewport, const TextDrawContext& ctx) const;
|
||||
|
||||
Vec2 GetRestoredFontSize(const TextDrawContext& ctx) const;
|
||||
|
||||
bool UpdateTexture();
|
||||
|
||||
void ScaleCoord(float& x, float& y) const;
|
||||
void ScaleCoord(const RHI::Viewport& viewport, float& x, float& y) const;
|
||||
|
||||
void InitWindowContext();
|
||||
void InitViewportContext();
|
||||
void InitDefaultWindowContext();
|
||||
void InitDefaultViewportContext();
|
||||
|
||||
void OnBootstrapSceneReady(AZ::RPI::Scene* bootstrapScene) override;
|
||||
|
||||
@@ -272,8 +294,8 @@ namespace AZ
|
||||
size_t m_fontBufferSize = 0;
|
||||
unsigned char* m_fontBuffer = nullptr;
|
||||
|
||||
AZStd::shared_ptr<RPI::WindowContext> m_windowContext;
|
||||
AZStd::shared_ptr<AZ::RPI::ViewportContext> m_viewportContext;
|
||||
AZStd::shared_ptr<RPI::WindowContext> m_defaultWindowContext;
|
||||
AZStd::shared_ptr<AZ::RPI::ViewportContext> m_defaultViewportContext;
|
||||
|
||||
AZ::Data::Instance<AZ::RPI::StreamingImage> m_fontStreamingImage;
|
||||
AZ::RHI::Ptr<AZ::RHI::Image> m_fontImage;
|
||||
@@ -296,8 +318,6 @@ namespace AZ
|
||||
|
||||
FontShaderData m_fontShaderData;
|
||||
|
||||
AZ::RHI::Ptr<AZ::RPI::DynamicDrawContext> m_dynamicDraw;
|
||||
|
||||
bool m_monospacedFont = false; //!< True if this font is fixed/monospaced, false otherwise (obtained from FreeType)
|
||||
|
||||
float m_sizeRatio = IFFontConstants::defaultSizeRatio;
|
||||
@@ -325,25 +345,25 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
inline void AZ::FFont::InitWindowContext()
|
||||
inline void AZ::FFont::InitDefaultWindowContext()
|
||||
{
|
||||
if (!m_windowContext)
|
||||
if (!m_defaultWindowContext)
|
||||
{
|
||||
// font is created before window & viewport in the editor so need to do late init
|
||||
// TODO need to deal with multiple windows, such as the editor
|
||||
AZ::Render::Bootstrap::DefaultWindowBus::BroadcastResult(m_windowContext, &AZ::Render::Bootstrap::DefaultWindowInterface::GetDefaultWindowContext);
|
||||
AZ_Assert(m_windowContext, "Unable to get the main window context");
|
||||
AZ::Render::Bootstrap::DefaultWindowBus::BroadcastResult(m_defaultWindowContext, &AZ::Render::Bootstrap::DefaultWindowInterface::GetDefaultWindowContext);
|
||||
AZ_Assert(m_defaultWindowContext, "Unable to get the main window context");
|
||||
}
|
||||
}
|
||||
|
||||
inline void AZ::FFont::InitViewportContext()
|
||||
inline void AZ::FFont::InitDefaultViewportContext()
|
||||
{
|
||||
if (!m_viewportContext)
|
||||
if (!m_defaultViewportContext)
|
||||
{
|
||||
// font is created before window & viewport in the editor so need to do late init
|
||||
auto viewContextManager = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
|
||||
m_viewportContext = viewContextManager->GetViewportContextByName(viewContextManager->GetDefaultViewportContextName());
|
||||
AZ_Assert(m_viewportContext, "Unable to get the viewport context");
|
||||
m_defaultViewportContext = viewContextManager->GetViewportContextByName(viewContextManager->GetDefaultViewportContextName());
|
||||
AZ_Assert(m_defaultViewportContext, "Unable to get the viewport context");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,12 @@
|
||||
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzCore/std/parallel/lock.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzFramework/Archive/IArchive.h>
|
||||
|
||||
#include <Atom/RPI.Public/RPIUtils.h>
|
||||
#include <Atom/RPI.Public/DynamicDraw/DynamicDrawInterface.h>
|
||||
|
||||
// Static member definitions
|
||||
const AZ::AtomFont::GlyphSize AZ::AtomFont::defaultGlyphSize = AZ::AtomFont::GlyphSize(ICryFont::defaultGlyphSizeX, ICryFont::defaultGlyphSizeY);
|
||||
@@ -348,10 +352,14 @@ AZ::AtomFont::AtomFont(ISystem* system)
|
||||
REGISTER_COMMAND("r_ReloadFonts", ReloadFonts, VF_NULL,
|
||||
"Reload all fonts");
|
||||
#endif
|
||||
AZ::Interface<AzFramework::FontQueryInterface>::Register(this);
|
||||
}
|
||||
|
||||
AZ::AtomFont::~AtomFont()
|
||||
{
|
||||
AZ::Interface<AzFramework::FontQueryInterface>::Unregister(this);
|
||||
m_defaultFontDrawInterface = nullptr;
|
||||
|
||||
// Persist fonts for application lifetime to prevent unnecessary work
|
||||
m_persistedFontFamilies.clear();
|
||||
|
||||
@@ -372,24 +380,41 @@ IFFont* AZ::AtomFont::NewFont(const char* fontName)
|
||||
{
|
||||
string name = fontName;
|
||||
name.MakeLower();
|
||||
AzFramework::FontId fontId = GetFontId(name.c_str());
|
||||
|
||||
FontMapItor it = m_fonts.find(CONST_TEMP_STRING(name.c_str()));
|
||||
FontMapItor it = m_fonts.find(fontId);
|
||||
if (it != m_fonts.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
FFont* font = new FFont(this, name.c_str());
|
||||
m_fonts.insert(FontMapItor::value_type(name, font));
|
||||
m_fonts.insert(FontMapItor::value_type(fontId, font));
|
||||
if(!m_defaultFontDrawInterface)
|
||||
{
|
||||
m_defaultFontDrawInterface = static_cast<AzFramework::FontDrawInterface*>(font);
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
IFFont* AZ::AtomFont::GetFont(const char* fontName) const
|
||||
{
|
||||
FontMapConstItor it = m_fonts.find(CONST_TEMP_STRING(string(fontName).MakeLower()));
|
||||
AzFramework::FontId fontId = GetFontId(string(fontName).MakeLower().c_str());
|
||||
FontMapConstItor it = m_fonts.find(fontId);
|
||||
return it != m_fonts.end() ? it->second : 0;
|
||||
}
|
||||
|
||||
AzFramework::FontDrawInterface* AZ::AtomFont::GetFontDrawInterface(AzFramework::FontId fontId) const
|
||||
{
|
||||
FontMapConstItor it = m_fonts.find(fontId);
|
||||
return (it != m_fonts.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
AzFramework::FontDrawInterface* AZ::AtomFont::GetDefaultFontDrawInterface() const
|
||||
{
|
||||
return m_defaultFontDrawInterface;
|
||||
}
|
||||
|
||||
FontFamilyPtr AZ::AtomFont::LoadFontFamily(const char* fontFamilyName)
|
||||
{
|
||||
FontFamilyPtr fontFamily(nullptr);
|
||||
@@ -648,7 +673,8 @@ void AZ::AtomFont::ReloadAllFonts()
|
||||
|
||||
void AZ::AtomFont::UnregisterFont(const char* fontName)
|
||||
{
|
||||
FontMapItor it = m_fonts.find(CONST_TEMP_STRING(fontName));
|
||||
AzFramework::FontId fontId = GetFontId(string(fontName).MakeLower().c_str());
|
||||
FontMapItor it = m_fonts.find(fontId);
|
||||
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
IFFont* fontPtr = it->second;
|
||||
@@ -823,5 +849,49 @@ XmlNodeRef AZ::AtomFont::LoadFontFamilyXml(const char* fontFamilyName, string& o
|
||||
return root;
|
||||
}
|
||||
|
||||
void AZ::AtomFont::SceneAboutToBeRemoved(AzFramework::Scene& scene)
|
||||
{
|
||||
AZ::RPI::Scene* rpiScene = scene.GetSubsystem<AZ::RPI::Scene>();
|
||||
|
||||
AZStd::lock_guard<AZStd::shared_mutex> lock(m_sceneToDynamicDrawMutex);
|
||||
if ( auto it = m_sceneToDynamicDrawMap.find(rpiScene); it != m_sceneToDynamicDrawMap.end())
|
||||
{
|
||||
m_sceneToDynamicDrawMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
AZ::RHI::Ptr<AZ::RPI::DynamicDrawContext> AZ::AtomFont::GetOrCreateDynamicDrawForScene(AZ::RPI::Scene* scene)
|
||||
{
|
||||
static const char* shaderFilepath = "Shaders/SimpleTextured.azshader";
|
||||
|
||||
{
|
||||
// shared lock while reading
|
||||
AZStd::shared_lock<AZStd::shared_mutex> lock(m_sceneToDynamicDrawMutex);
|
||||
|
||||
if (auto it = m_sceneToDynamicDrawMap.find(scene); it != m_sceneToDynamicDrawMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
// Create and initialize DynamicDrawContext for font draw
|
||||
AZ::RHI::Ptr<AZ::RPI::DynamicDrawContext> dynamicDraw = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(scene);
|
||||
|
||||
Data::Instance<RPI::Shader> shader = AZ::RPI::LoadShader(shaderFilepath);
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("false")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true")));
|
||||
dynamicDraw->InitShaderWithVariant(shader, &shaderOptions);
|
||||
dynamicDraw->InitVertexFormat({{"POSITION", RHI::Format::R32G32B32_FLOAT}, {"COLOR", RHI::Format::R8G8B8A8_UNORM}, {"TEXCOORD0", RHI::Format::R32G32_FLOAT}});
|
||||
dynamicDraw->EndInit();
|
||||
|
||||
// exclusive lock while writing
|
||||
AZStd::lock_guard<AZStd::shared_mutex> lock(m_sceneToDynamicDrawMutex);
|
||||
m_sceneToDynamicDrawMap.insert(AZStd::make_pair(scene, dynamicDraw));
|
||||
|
||||
return dynamicDraw;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <AzCore/Math/MatrixUtils.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
|
||||
#include <AzFramework/Viewport/ViewportScreen.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
|
||||
#include <AzFramework/Archive/Archive.h>
|
||||
|
||||
#include <AtomLyIntegration/AtomFont/FFont.h>
|
||||
@@ -42,6 +45,8 @@
|
||||
#include <Atom/RPI.Public/View.h>
|
||||
#include <Atom/RPI.Public/Image/ImageSystemInterface.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImagePool.h>
|
||||
#include <Atom/RPI.Public/ViewportContextManager.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
#include <Atom/RHI/Factory.h>
|
||||
#include <Atom/RHI/DrawPacket.h>
|
||||
@@ -49,6 +54,7 @@
|
||||
|
||||
#include <Atom/RHI.Reflect/InputStreamLayoutBuilder.h>
|
||||
|
||||
static const AZ::Vector2 UiDraw_TextSizeFactor = AZ::Vector2(12.0f, 12.0f);
|
||||
static const int TabCharCount = 4;
|
||||
// set buffer sizes to hold max characters that can be drawn in 1 DrawString call
|
||||
static const size_t MaxVerts = 8 * 1024; // 2048 quads
|
||||
@@ -78,6 +84,7 @@ AZ::FFont::FFont(AtomFont* atomFont, const char* fontName)
|
||||
AZ::Render::Bootstrap::NotificationBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
|
||||
bool AZ::FFont::InitFont()
|
||||
{
|
||||
if (m_fontInitialized)
|
||||
@@ -85,24 +92,14 @@ bool AZ::FFont::InitFont()
|
||||
return true;
|
||||
}
|
||||
|
||||
InitWindowContext();
|
||||
InitViewportContext();
|
||||
|
||||
const char* shaderFilepath = "Shaders/SimpleTextured.azshader";
|
||||
InitDefaultWindowContext();
|
||||
InitDefaultViewportContext();
|
||||
|
||||
// Create and initialize DynamicDrawContext for font draw
|
||||
m_dynamicDraw = RPI::DynamicDrawInterface::Get()->CreateDynamicDrawContext(m_viewportContext->GetRenderScene().get());
|
||||
|
||||
Data::Instance<RPI::Shader> shader = AZ::RPI::LoadShader(shaderFilepath);
|
||||
AZ::RPI::ShaderOptionList shaderOptions;
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_useColorChannels"), AZ::Name("false")));
|
||||
shaderOptions.push_back(AZ::RPI::ShaderOption(AZ::Name("o_clamp"), AZ::Name("true")));
|
||||
m_dynamicDraw->InitShaderWithVariant(shader, &shaderOptions);
|
||||
m_dynamicDraw->InitVertexFormat({{"POSITION", RHI::Format::R32G32B32_FLOAT}, {"COLOR", RHI::Format::R8G8B8A8_UNORM}, {"TEXCOORD0", RHI::Format::R32G32_FLOAT}});
|
||||
m_dynamicDraw->EndInit();
|
||||
AZ::RPI::Ptr<AZ::RPI::DynamicDrawContext> dynamicDraw = m_atomFont->GetOrCreateDynamicDrawForScene(m_defaultViewportContext->GetRenderScene().get());
|
||||
|
||||
// Save draw srg input indices for later use
|
||||
Data::Instance<RPI::ShaderResourceGroup> drawSrg = m_dynamicDraw->NewDrawSrg();
|
||||
Data::Instance<RPI::ShaderResourceGroup> drawSrg = dynamicDraw->NewDrawSrg();
|
||||
const RHI::ShaderResourceGroupLayout* layout = drawSrg->GetAsset()->GetLayout();
|
||||
|
||||
m_fontShaderData.m_imageInputIndex = layout->FindShaderInputImageIndex(AZ::Name(ShaderInputs::TextureIndexName));
|
||||
@@ -257,27 +254,39 @@ void AZ::FFont::Free()
|
||||
|
||||
void AZ::FFont::DrawString(float x, float y, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
|
||||
{
|
||||
if (!str || !m_vertexBuffer)
|
||||
if (!str)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawStringUInternal(x, y, 1.0f, str, asciiMultiLine, ctx);
|
||||
DrawStringUInternal(m_defaultWindowContext->GetViewport(), m_defaultViewportContext.get(), x, y, 1.0f, str, asciiMultiLine, ctx);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawString(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
|
||||
{
|
||||
if (!str || !m_vertexBuffer)
|
||||
if (!str)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawStringUInternal(x, y, z, str, asciiMultiLine, ctx);
|
||||
DrawStringUInternal(m_defaultWindowContext->GetViewport(), m_defaultViewportContext.get(), x, y, z, str, asciiMultiLine, ctx);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawStringUInternal(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
|
||||
void AZ::FFont::DrawStringUInternal(
|
||||
const RHI::Viewport& viewport,
|
||||
RPI::ViewportContext* viewportContext,
|
||||
float x,
|
||||
float y,
|
||||
float z,
|
||||
const char* str,
|
||||
const bool asciiMultiLine,
|
||||
const TextDrawContext& ctx)
|
||||
{
|
||||
if (!str || !m_fontTexture || ctx.m_fxIdx >= m_effects.size() || m_effects[ctx.m_fxIdx].m_passes.empty())
|
||||
if (!str
|
||||
|| !m_vertexBuffer // vertex buffer isn't created until BootstrapScene is ready, Editor tries to render text before that.
|
||||
|| !m_fontTexture
|
||||
|| ctx.m_fxIdx >= m_effects.size()
|
||||
|| m_effects[ctx.m_fxIdx].m_passes.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -296,7 +305,6 @@ void AZ::FFont::DrawStringUInternal(float x, float y, float z, const char* str,
|
||||
|
||||
const bool orthoMode = ctx.m_overrideViewProjMatrices;
|
||||
|
||||
const RHI::Viewport& viewport = m_windowContext->GetViewport();
|
||||
const float viewX = viewport.m_minX;
|
||||
const float viewY = viewport.m_minY;
|
||||
const float viewWidth = viewport.m_maxX - viewport.m_minX;
|
||||
@@ -307,7 +315,7 @@ void AZ::FFont::DrawStringUInternal(float x, float y, float z, const char* str,
|
||||
Matrix4x4 modelViewProjMat;
|
||||
if (!orthoMode)
|
||||
{
|
||||
AZ::RPI::ViewPtr view = m_viewportContext->GetDefaultView();
|
||||
AZ::RPI::ViewPtr view = viewportContext->GetDefaultView();
|
||||
modelViewProjMat = view->GetWorldToClipMatrix();
|
||||
}
|
||||
else
|
||||
@@ -322,7 +330,7 @@ void AZ::FFont::DrawStringUInternal(float x, float y, float z, const char* str,
|
||||
size_t startingVertexCount = m_vertexCount;
|
||||
|
||||
// Local function that is passed into CreateQuadsForText as the AddQuad function
|
||||
AddFunction AddQuad = [this, startingVertexCount]
|
||||
AZ::FFont::AddFunction AddQuad = [this, startingVertexCount]
|
||||
(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, const Vec2& tc0, const Vec2& tc1, const Vec2& tc2, const Vec2& tc3, uint32_t packedColor)
|
||||
{
|
||||
const bool vertexSpaceLeft = m_vertexCount + 4 < MaxVerts;
|
||||
@@ -367,18 +375,19 @@ void AZ::FFont::DrawStringUInternal(float x, float y, float z, const char* str,
|
||||
int numQuads = 0;
|
||||
{
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_vertexDataMutex);
|
||||
numQuads = CreateQuadsForText(x, y, z, str, asciiMultiLine, ctx, AddQuad);
|
||||
numQuads = CreateQuadsForText(viewport, x, y, z, str, asciiMultiLine, ctx, AddQuad);
|
||||
}
|
||||
|
||||
if (numQuads)
|
||||
{
|
||||
auto dynamicDraw = m_atomFont->GetOrCreateDynamicDrawForScene(viewportContext->GetRenderScene().get());
|
||||
//setup per draw srg
|
||||
auto drawSrg = m_dynamicDraw->NewDrawSrg();
|
||||
auto drawSrg = dynamicDraw->NewDrawSrg();
|
||||
drawSrg->SetConstant(m_fontShaderData.m_viewProjInputIndex, modelViewProjMat);
|
||||
drawSrg->SetImageView(m_fontShaderData.m_imageInputIndex, m_fontStreamingImage->GetImageView());
|
||||
drawSrg->Compile();
|
||||
|
||||
m_dynamicDraw->DrawIndexed(m_vertexBuffer, m_vertexCount, m_indexBuffer, m_indexCount, RHI::IndexFormat::Uint16, drawSrg);
|
||||
dynamicDraw->DrawIndexed(m_vertexBuffer, m_vertexCount, m_indexBuffer, m_indexCount, RHI::IndexFormat::Uint16, drawSrg);
|
||||
m_indexCount = 0;
|
||||
m_vertexCount = 0;
|
||||
}
|
||||
@@ -391,10 +400,14 @@ Vec2 AZ::FFont::GetTextSize(const char* str, const bool asciiMultiLine, const Te
|
||||
return Vec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
return GetTextSizeUInternal(str, asciiMultiLine, ctx);
|
||||
return GetTextSizeUInternal(m_defaultWindowContext->GetViewport(), str, asciiMultiLine, ctx);
|
||||
}
|
||||
|
||||
Vec2 AZ::FFont::GetTextSizeUInternal(const char* str, const bool asciiMultiLine, const TextDrawContext& ctx)
|
||||
Vec2 AZ::FFont::GetTextSizeUInternal(
|
||||
const RHI::Viewport& viewport,
|
||||
const char* str,
|
||||
const bool asciiMultiLine,
|
||||
const TextDrawContext& ctx)
|
||||
{
|
||||
const size_t fxSize = m_effects.size();
|
||||
|
||||
@@ -411,12 +424,12 @@ Vec2 AZ::FFont::GetTextSizeUInternal(const char* str, const bool asciiMultiLine,
|
||||
Vec2 size = ctx.m_size;
|
||||
if (ctx.m_sizeIn800x600)
|
||||
{
|
||||
ScaleCoord(size.x, size.y);
|
||||
ScaleCoord(viewport, size.x, size.y);
|
||||
}
|
||||
|
||||
// This scaling takes into account the logical size of the font relative
|
||||
// to any additional scaling applied (such as from "size ratio").
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx));
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(viewport, ctx));
|
||||
|
||||
float maxW = 0;
|
||||
float maxH = 0;
|
||||
@@ -733,7 +746,7 @@ uint32_t AZ::FFont::WriteTextQuadsToBuffers(SVF_P2F_C4B_T2F_F4B* verts, uint16_t
|
||||
return true;
|
||||
};
|
||||
|
||||
CreateQuadsForText(x, y, z, str, asciiMultiLine, ctx, AddQuad);
|
||||
CreateQuadsForText(m_defaultWindowContext->GetViewport(), x, y, z, str, asciiMultiLine, ctx, AddQuad);
|
||||
|
||||
return numQuadsWritten;
|
||||
}
|
||||
@@ -743,7 +756,7 @@ uint32_t AZ::FFont::GetFontTextureVersion()
|
||||
return m_fontImageVersion;
|
||||
}
|
||||
|
||||
int AZ::FFont::CreateQuadsForText(float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx,
|
||||
int AZ::FFont::CreateQuadsForText(const RHI::Viewport& viewport, float x, float y, float z, const char* str, const bool asciiMultiLine, const TextDrawContext& ctx,
|
||||
AddFunction AddQuad)
|
||||
{
|
||||
int numQuads = 0;
|
||||
@@ -768,17 +781,17 @@ int AZ::FFont::CreateQuadsForText(float x, float y, float z, const char* str, co
|
||||
Vec2 size = ctx.m_size;
|
||||
if (ctx.m_sizeIn800x600)
|
||||
{
|
||||
ScaleCoord(size.x, size.y);
|
||||
ScaleCoord(viewport, size.x, size.y);
|
||||
}
|
||||
|
||||
// This scaling takes into account the logical size of the font relative
|
||||
// to any additional scaling applied (such as from "size ratio").
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx));
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(viewport, ctx));
|
||||
|
||||
Vec2 baseXY = Vec2(x, y); // in pixels
|
||||
if (ctx.m_sizeIn800x600)
|
||||
{
|
||||
ScaleCoord(baseXY.x, baseXY.y);
|
||||
ScaleCoord(viewport, baseXY.x, baseXY.y);
|
||||
}
|
||||
|
||||
// snap for pixel perfect rendering (better quality for text)
|
||||
@@ -826,7 +839,7 @@ int AZ::FFont::CreateQuadsForText(float x, float y, float z, const char* str, co
|
||||
ColorB tempColor(255, 255, 255, 255);
|
||||
uint32_t frameColor = tempColor.pack_abgr8888(); //note: this ends up in r,g,b,a order on little-endian machines
|
||||
|
||||
Vec2 textSize = GetTextSizeUInternal(str, asciiMultiLine, ctx);
|
||||
Vec2 textSize = GetTextSizeUInternal(viewport, str, asciiMultiLine, ctx);
|
||||
|
||||
float x0 = baseXY.x - 12;
|
||||
float y0 = baseXY.y - 6;
|
||||
@@ -1107,13 +1120,13 @@ int AZ::FFont::CreateQuadsForText(float x, float y, float z, const char* str, co
|
||||
return numQuads;
|
||||
}
|
||||
|
||||
AZ::FFont::TextScaleInfoInternal AZ::FFont::CalculateScaleInternal(const TextDrawContext& ctx) const
|
||||
AZ::FFont::TextScaleInfoInternal AZ::FFont::CalculateScaleInternal(const RHI::Viewport& viewport, const TextDrawContext& ctx) const
|
||||
{
|
||||
Vec2 size = GetRestoredFontSize(ctx); // in pixel
|
||||
|
||||
if (ctx.m_sizeIn800x600)
|
||||
{
|
||||
ScaleCoord(size.x, size.y);
|
||||
ScaleCoord(viewport, size.x, size.y);
|
||||
}
|
||||
|
||||
float rcpCellWidth;
|
||||
@@ -1196,7 +1209,7 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
|
||||
maxWidth = gEnv->pRenderer->ScaleCoordX(maxWidth);
|
||||
}
|
||||
|
||||
Vec2 strSize = GetTextSizeUInternal(result.c_str(), true, ctx);
|
||||
Vec2 strSize = GetTextSize(result.c_str(), true, ctx);
|
||||
|
||||
if (strSize.x <= maxWidth)
|
||||
{
|
||||
@@ -1245,7 +1258,7 @@ void AZ::FFont::WrapText(string& result, float maxWidth, const char* str, const
|
||||
// Note: This is not unicode compatible, since char-width depends on surrounding context (ie, combining diacritics etc)
|
||||
char codepoint[5];
|
||||
Unicode::Convert(codepoint, ch);
|
||||
curCharWidth = GetTextSizeUInternal(codepoint, true, ctx).x;
|
||||
curCharWidth = GetTextSize(codepoint, true, ctx).x;
|
||||
|
||||
// keep track of spaces
|
||||
// they are good for splitting the string
|
||||
@@ -1425,7 +1438,12 @@ void AZ::FFont::AddCharsToFontTexture(const char* chars, int glyphSizeX, int gly
|
||||
|
||||
Vec2 AZ::FFont::GetKerning(uint32_t leftGlyph, uint32_t rightGlyph, const TextDrawContext& ctx) const
|
||||
{
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx));
|
||||
return GetKerningInternal(m_defaultWindowContext->GetViewport(), leftGlyph, rightGlyph, ctx);
|
||||
}
|
||||
|
||||
Vec2 AZ::FFont::GetKerningInternal(const RHI::Viewport& viewport, uint32_t leftGlyph, uint32_t rightGlyph, const TextDrawContext& ctx) const
|
||||
{
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(viewport, ctx));
|
||||
return m_fontTexture->GetKerning(leftGlyph, rightGlyph) * scaleInfo.scale.x;
|
||||
}
|
||||
|
||||
@@ -1436,12 +1454,18 @@ float AZ::FFont::GetAscender(const TextDrawContext& ctx) const
|
||||
|
||||
float AZ::FFont::GetBaseline(const TextDrawContext& ctx) const
|
||||
{
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(ctx));
|
||||
return GetBaselineInternal(m_defaultWindowContext->GetViewport(), ctx);
|
||||
}
|
||||
|
||||
float AZ::FFont::GetBaselineInternal(const RHI::Viewport& viewport, const TextDrawContext& ctx) const
|
||||
{
|
||||
const TextScaleInfoInternal scaleInfo(CalculateScaleInternal(viewport, ctx));
|
||||
// Calculate baseline the same way as the font renderer which uses the glyph height * size ratio.
|
||||
// Adding 1 because FontTexture always adds 1 to the char height in GetTextureCoord
|
||||
return (round(m_fontTexture->GetCellHeight() * GetSizeRatio()) + 1.0f) * scaleInfo.scale.y;
|
||||
}
|
||||
|
||||
|
||||
bool AZ::FFont::InitTexture()
|
||||
{
|
||||
using namespace AZ;
|
||||
@@ -1565,14 +1589,8 @@ Vec2 AZ::FFont::GetRestoredFontSize(const TextDrawContext& ctx) const
|
||||
return Vec2(ctx.m_size.x * restoringScale, ctx.m_size.y * restoringScale);
|
||||
}
|
||||
|
||||
void AZ::FFont::ScaleCoord(float& x, float& y) const
|
||||
void AZ::FFont::ScaleCoord(const RHI::Viewport& viewport, float& x, float& y) const
|
||||
{
|
||||
if (!m_windowContext)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const RHI::Viewport& viewport = m_windowContext->GetViewport();
|
||||
float width = viewport.m_maxX - viewport.m_minX;
|
||||
float height = viewport.m_maxY - viewport.m_minY;
|
||||
|
||||
@@ -1580,11 +1598,161 @@ void AZ::FFont::ScaleCoord(float& x, float& y) const
|
||||
y *= height / WindowScaleHeight;
|
||||
}
|
||||
|
||||
|
||||
void AZ::FFont::OnBootstrapSceneReady([[maybe_unused]] AZ::RPI::Scene* bootstrapScene)
|
||||
{
|
||||
InitFont();
|
||||
}
|
||||
|
||||
static void SetCommonContextFlags(AZ::TextDrawContext& ctx, const AzFramework::TextDrawParameters& params)
|
||||
{
|
||||
if (params.m_hAlign == AzFramework::TextHorizontalAlignment::Center)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_Center;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (params.m_hAlign == AzFramework::TextHorizontalAlignment::Right)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_Right;
|
||||
}
|
||||
|
||||
if (params.m_vAlign == AzFramework::TextVerticalAlignment::Center)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_CenterV;
|
||||
}
|
||||
|
||||
if (params.m_vAlign == AzFramework::TextVerticalAlignment::Bottom)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_Bottom;
|
||||
}
|
||||
|
||||
if (params.m_monospace)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_Monospace;
|
||||
}
|
||||
|
||||
if (params.m_depthTest)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_DepthTest;
|
||||
}
|
||||
|
||||
if (params.m_virtual800x600ScreenSize)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_800x600;
|
||||
}
|
||||
|
||||
if (!params.m_scaleWithWindow)
|
||||
{
|
||||
ctx.m_drawTextFlags |= eDrawText_FixedSize;
|
||||
}
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawScreenAlignedText2d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string)
|
||||
{
|
||||
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
|
||||
string.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Code mostly duplicated from CRenderer::Draw2dTextWithDepth
|
||||
float posX = params.m_position.GetX();
|
||||
float posY = params.m_position.GetY();
|
||||
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
|
||||
const AZ::RHI::Viewport& viewport = viewportContext->GetWindowContext()->GetViewport();
|
||||
if (params.m_virtual800x600ScreenSize)
|
||||
{
|
||||
posX *= WindowScaleWidth / (viewport.m_maxX - viewport.m_minX);
|
||||
posY *= WindowScaleHeight / (viewport.m_maxY - viewport.m_minY);
|
||||
}
|
||||
TextDrawContext ctx;
|
||||
ctx.SetBaseState(GS_NODEPTHTEST);
|
||||
ctx.SetColor(AZColorToLYColorF(params.m_color));
|
||||
ctx.SetCharWidthScale((params.m_monospace || params.m_scaleWithWindow) ? 0.5f : 1.0f);
|
||||
ctx.EnableFrame(false);
|
||||
ctx.SetProportional(!params.m_monospace && params.m_scaleWithWindow);
|
||||
ctx.SetSizeIn800x600(params.m_scaleWithWindow && params.m_virtual800x600ScreenSize);
|
||||
ctx.SetSize(AZVec2ToLYVec2(UiDraw_TextSizeFactor * params.m_scale));
|
||||
if (params.m_monospace || !params.m_scaleWithWindow)
|
||||
{
|
||||
ScaleCoord(viewport, posX, posY);
|
||||
}
|
||||
|
||||
if (params.m_hAlign != AzFramework::TextHorizontalAlignment::Left ||
|
||||
params.m_vAlign != AzFramework::TextVerticalAlignment::Top)
|
||||
{
|
||||
Vec2 textSize = GetTextSizeUInternal(viewport, string.data(), params.m_multiline, ctx);
|
||||
|
||||
// If we're using virtual 800x600 coordinates, convert the text size from
|
||||
// pixels to that before using it as an offset.
|
||||
if (ctx.m_sizeIn800x600)
|
||||
{
|
||||
float width = 1.0f;
|
||||
float height = 1.0f;
|
||||
ScaleCoord(viewport, width, height);
|
||||
textSize.x /= width;
|
||||
textSize.y /= height;
|
||||
}
|
||||
|
||||
if (params.m_hAlign == AzFramework::TextHorizontalAlignment::Center)
|
||||
{
|
||||
posX -= textSize.x * 0.5f;
|
||||
}
|
||||
else if (params.m_hAlign == AzFramework::TextHorizontalAlignment::Right)
|
||||
{
|
||||
posX -= textSize.x;
|
||||
}
|
||||
|
||||
if (params.m_vAlign == AzFramework::TextVerticalAlignment::Center)
|
||||
{
|
||||
posY -= textSize.y * 0.5f;
|
||||
}
|
||||
else if (params.m_vAlign == AzFramework::TextVerticalAlignment::Bottom)
|
||||
{
|
||||
posY -= textSize.y;
|
||||
}
|
||||
}
|
||||
SetCommonContextFlags(ctx, params);
|
||||
ctx.m_drawTextFlags |= eDrawText_2D;
|
||||
|
||||
DrawStringUInternal(
|
||||
viewport,
|
||||
viewportContext,
|
||||
posX,
|
||||
posY,
|
||||
params.m_position.GetZ(), // Z
|
||||
string.data(),
|
||||
params.m_multiline,
|
||||
ctx
|
||||
);
|
||||
}
|
||||
|
||||
void AZ::FFont::DrawScreenAlignedText3d(
|
||||
const AzFramework::TextDrawParameters& params,
|
||||
const AZStd::string_view& string)
|
||||
{
|
||||
if (params.m_drawViewportId == AzFramework::InvalidViewportId ||
|
||||
string.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZ::RPI::ViewportContext* viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetViewportContextById(params.m_drawViewportId).get();
|
||||
AZ::RPI::ViewPtr currentView = viewportContext->GetDefaultView();
|
||||
if (!currentView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZ::Vector3 positionNDC = AzFramework::WorldToScreenNDC(
|
||||
params.m_position,
|
||||
currentView->GetViewToWorldMatrix(),
|
||||
currentView->GetViewToClipMatrix()
|
||||
);
|
||||
AzFramework::TextDrawParameters param2d = params;
|
||||
param2d.m_position = positionNDC;
|
||||
DrawScreenAlignedText2d(param2d, string);
|
||||
}
|
||||
|
||||
#endif //USE_NULLFONT_ALWAYS
|
||||
|
||||
|
||||
+3
@@ -73,6 +73,9 @@ namespace AZ
|
||||
|
||||
bool RequiresShapeComponent() const;
|
||||
|
||||
//! Returns true if the light type is anything other than unknown.
|
||||
bool LightTypeIsSelected() const;
|
||||
|
||||
//! Returns true if m_attenuationRadiusMode is set to LightAttenuationRadiusMode::Automatic
|
||||
bool IsAttenuationRadiusModeAutomatic() const;
|
||||
|
||||
|
||||
+5
@@ -73,6 +73,11 @@ namespace AZ
|
||||
|| m_lightType == LightType::Polygon;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::LightTypeIsSelected() const
|
||||
{
|
||||
return m_lightType != LightType::Unknown;
|
||||
}
|
||||
|
||||
bool AreaLightComponentConfig::IsAttenuationRadiusModeAutomatic() const
|
||||
{
|
||||
return m_attenuationRadiusMode == LightAttenuationRadiusMode::Automatic;
|
||||
|
||||
+9
@@ -234,6 +234,11 @@ namespace AZ::Render
|
||||
!(m_configuration.m_lightType == AreaLightComponentConfig::LightType::Polygon && m_configuration.m_shapeType != PoylgonShapeTypeId),
|
||||
"The light type is a polygon, but the shape component is not.");
|
||||
}
|
||||
|
||||
if (m_configuration.m_lightType == AreaLightComponentConfig::LightType::SimpleSpot)
|
||||
{
|
||||
m_configuration.m_enableShutters = true; // Simple spot always has shutters.
|
||||
}
|
||||
}
|
||||
|
||||
void AreaLightComponentController::ConfigurationChanged()
|
||||
@@ -620,6 +625,10 @@ namespace AZ::Render
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_lightShapeDelegate)
|
||||
{
|
||||
m_lightShapeDelegate->SetConfig(&m_configuration);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AZ::Render
|
||||
|
||||
@@ -51,14 +51,52 @@ namespace AZ::Render
|
||||
return m_shapeBus->GetRadius() * GetTransform().GetScale().GetMaxElement();
|
||||
}
|
||||
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
void DiskLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& /*color*/, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
debugDisplay.PushMatrix(transform);
|
||||
float radius = GetConfig()->m_attenuationRadius;
|
||||
|
||||
// Draw a disk for the attenuation radius
|
||||
debugDisplay.DrawWireSphere(transform.GetTranslation(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity));
|
||||
if (GetConfig()->m_enableShutters)
|
||||
{
|
||||
|
||||
float innerRadians = DegToRad(GetConfig()->m_innerShutterAngleDegrees);
|
||||
float outerRadians = DegToRad(GetConfig()->m_outerShutterAngleDegrees);
|
||||
|
||||
// Draw a cone using the cone angle and attenuation radius
|
||||
innerRadians = GetMin(innerRadians, outerRadians);
|
||||
float coneRadiusInner = sin(innerRadians) * radius;
|
||||
float coneHeightInner = cos(innerRadians) * radius;
|
||||
float coneRadiusOuter = sin(outerRadians) * radius;
|
||||
float coneHeightOuter = cos(outerRadians) * radius;
|
||||
|
||||
auto DrawConicalFrustum = [&debugDisplay](uint32_t numRadiusLines, float topRadius, float bottomRadius, float height, float brightness)
|
||||
{
|
||||
debugDisplay.SetColor(Color(brightness, brightness, brightness, 1.0f));
|
||||
debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), bottomRadius);
|
||||
|
||||
for (uint32_t i = 0; i < numRadiusLines; ++i)
|
||||
{
|
||||
float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
|
||||
debugDisplay.DrawLine(
|
||||
Vector3(cos(radiusLineAngle) * topRadius, sin(radiusLineAngle) * topRadius, 0),
|
||||
Vector3(cos(radiusLineAngle) * bottomRadius, sin(radiusLineAngle) * bottomRadius, height)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
DrawConicalFrustum(16, m_shapeBus->GetRadius(), m_shapeBus->GetRadius() + coneRadiusInner, coneHeightInner, 1.0f);
|
||||
DrawConicalFrustum(16, m_shapeBus->GetRadius(), m_shapeBus->GetRadius() + coneRadiusOuter, coneHeightOuter, 0.65f);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
debugDisplay.DrawWireDisk(Vector3::CreateZero(), Vector3::CreateAxisZ(), radius);
|
||||
debugDisplay.DrawArc(Vector3::CreateZero(), radius, 90.0f, 180.0f, -3.0f, 0);
|
||||
debugDisplay.DrawArc(Vector3::CreateZero(), radius, 0.0f, 180.0f, 3.0f, 1);
|
||||
}
|
||||
debugDisplay.PopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+32
-25
@@ -67,50 +67,56 @@ namespace AZ
|
||||
editContext->Class<AreaLightComponentConfig>(
|
||||
"AreaLightComponentConfig", "")
|
||||
->ClassElement(Edit::ClassElements::EditorData, "")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_lightType, "Light Type", "Which type of light this component represents.")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Unknown, "Choose a Light Type")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Sphere, "Point (Sphere)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimplePoint, "Point (Simple)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SpotDisk, "Spot (Disk)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimpleSpot, "Spot (Simple)")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_lightType, "Light type", "Which type of light this component represents.")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Unknown, "Choose a light type")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Sphere, "Point (sphere)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimplePoint, "Point (simple punctual)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SpotDisk, "Spot (disk)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::SimpleSpot, "Spot (simple punctual)")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Capsule, "Capsule")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Quad, "Quad")
|
||||
->EnumAttribute(AreaLightComponentConfig::LightType::Polygon, "Polygon")
|
||||
->DataElement(Edit::UIHandlers::Color, &AreaLightComponentConfig::m_color, "Color", "Color of the light")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->Attribute("ColorEditorConfiguration", RPI::ColorUtils::GetLinearRgbEditorConfig())
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity Mode", "Allows specifying which photometric unit to work in.")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_intensityMode, "Intensity mode", "Allows specifying which photometric unit to work in.")
|
||||
->Attribute(AZ::Edit::Attributes::EnumValues, &AreaLightComponentConfig::GetValidPhotometricUnits)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_intensity, "Intensity", "Intensity of the light in the set photometric unit.")
|
||||
->Attribute(Edit::Attributes::Min, &AreaLightComponentConfig::GetIntensityMin)
|
||||
->Attribute(Edit::Attributes::Max, &AreaLightComponentConfig::GetIntensityMax)
|
||||
->Attribute(Edit::Attributes::SoftMin, &AreaLightComponentConfig::GetIntensitySoftMin)
|
||||
->Attribute(Edit::Attributes::SoftMax, &AreaLightComponentConfig::GetIntensitySoftMax)
|
||||
->Attribute(Edit::Attributes::Suffix, &AreaLightComponentConfig::GetIntensitySuffix)
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_lightEmitsBothDirections, "Both Directions", "Whether light should emit from both sides of the surface or just the front")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_lightEmitsBothDirections, "Both directions", "Whether light should emit from both sides of the surface or just the front")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsBothDirections)
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_useFastApproximation, "Fast Approximation", "Whether the light should use the default high quality linear transformed cosine technique or a faster approximation.")
|
||||
->DataElement(Edit::UIHandlers::CheckBox, &AreaLightComponentConfig::m_useFastApproximation, "Fast approximation", "Whether the light should use the default high quality linear transformed cosine technique or a faster approximation.")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsFastApproximation)
|
||||
->ClassElement(Edit::ClassElements::Group, "Attenuation Radius")
|
||||
->ClassElement(Edit::ClassElements::Group, "Attenuation radius")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_attenuationRadiusMode, "Mode", "Controls whether the attenation radius is calculated automatically or set explicitly.")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Automatic, "Automatic")
|
||||
->EnumAttribute(LightAttenuationRadiusMode::Explicit, "Explicit")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_attenuationRadius, "Radius", "The distance at which this light no longer has an affect.")
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsAttenuationRadiusModeAutomatic)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::LightTypeIsSelected)
|
||||
|
||||
->ClassElement(Edit::ClassElements::Group, "Shutters")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShutters, "Enable Shutters", "Restrict the light to a specific beam angle depending on shape.")
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShutters, "Enable shutters", "Restrict the light to a specific beam angle depending on shape.")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::ShuttersMustBeEnabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_innerShutterAngleDegrees, "Inner Angle", "The inner angle of the shutters where the light beam begins to be occluded.")
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_innerShutterAngleDegrees, "Inner angle", "The inner angle of the shutters where the light beam begins to be occluded.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 180.0f)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShuttersDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_outerShutterAngleDegrees, "Outer Angle", "The outer angle of the shutters where the light beam is completely occluded.")
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_outerShutterAngleDegrees, "Outer angle", "The outer angle of the shutters where the light beam is completely occluded.")
|
||||
->Attribute(Edit::Attributes::Min, 0.0f)
|
||||
->Attribute(Edit::Attributes::Max, 180.0f)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShutters)
|
||||
@@ -119,9 +125,9 @@ namespace AZ
|
||||
->ClassElement(Edit::ClassElements::Group, "Shadows")
|
||||
->Attribute(Edit::Attributes::AutoExpand, true)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShadow, "Enable Shadow", "Enable shadow for the light")
|
||||
->DataElement(Edit::UIHandlers::Default, &AreaLightComponentConfig::m_enableShadow, "Enable shadow", "Enable shadow for the light")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowmapMaxSize, "Shadowmap Size", "Width/Height of shadowmap")
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowmapMaxSize, "Shadowmap size", "Width and height of shadowmap")
|
||||
->EnumAttribute(ShadowmapSize::Size256, " 256")
|
||||
->EnumAttribute(ShadowmapSize::Size512, " 512")
|
||||
->EnumAttribute(ShadowmapSize::Size1024, "1024")
|
||||
@@ -129,13 +135,13 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowFilterMethod, "Shadow Filter Method",
|
||||
->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowFilterMethod, "Shadow filter method",
|
||||
"Filtering method of edge-softening of shadows.\n"
|
||||
" None: no filtering\n"
|
||||
" PCF: Percentage-Closer Filtering\n"
|
||||
" ESM: Exponential Shadow Maps\n"
|
||||
" PCF: Percentage-closer Filtering\n"
|
||||
" ESM: Exponential shadow maps\n"
|
||||
" ESM+PCF: ESM with a PCF fallback\n"
|
||||
"For BehaviorContext (or TrackView), None=0, PCF=1, ESM=2, ESM+PCF=3")
|
||||
"For BehaviorContext (or track view), None=0, PCF=1, ESM=2, ESM+PCF=3")
|
||||
->EnumAttribute(ShadowFilterMethod::None, "None")
|
||||
->EnumAttribute(ShadowFilterMethod::Pcf, "PCF")
|
||||
->EnumAttribute(ShadowFilterMethod::Esm, "ESM")
|
||||
@@ -143,7 +149,7 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::AttributesAndValues)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_boundaryWidthInDegrees, "Softening Boundary Width",
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_boundaryWidthInDegrees, "Softening boundary width",
|
||||
"Width of the boundary between shadowed area and lit one. "
|
||||
"Units are in degrees. "
|
||||
"If this is 0, softening edge is disabled.")
|
||||
@@ -152,26 +158,27 @@ namespace AZ
|
||||
->Attribute(Edit::Attributes::Suffix, " deg")
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_predictionSampleCount, "Prediction Sample Count",
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_predictionSampleCount, "Prediction sample count",
|
||||
"Sample Count for prediction of whether the pixel is on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 16)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsPcfBoundarySearchDisabled)
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering Sample Count",
|
||||
->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_filteringSampleCount, "Filtering sample count",
|
||||
"It is used only when the pixel is predicted to be on the boundary. Specific to PCF and ESM+PCF.")
|
||||
->Attribute(Edit::Attributes::Min, 4)
|
||||
->Attribute(Edit::Attributes::Max, 64)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled)
|
||||
->DataElement(
|
||||
Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "Pcf Method",
|
||||
"Type of Pcf to use.\n"
|
||||
Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_pcfMethod, "Pcf method",
|
||||
"Type of PCF to use.\n"
|
||||
" Boundary search: do several taps to first determine if we are on a shadow boundary\n"
|
||||
" Bicubic: a smooth, fixed-size kernel \n")
|
||||
->EnumAttribute(PcfMethod::BoundarySearch, "Boundary Search")
|
||||
->EnumAttribute(PcfMethod::BoundarySearch, "Boundary search")
|
||||
->EnumAttribute(PcfMethod::Bicubic, "Bicubic")
|
||||
->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly)
|
||||
->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows)
|
||||
->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::IsShadowPcfDisabled);
|
||||
;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <Atom/Feature/CoreLights/PhotometricValue.h>
|
||||
#include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
|
||||
#include <LmbrCentral/Shape/SphereShapeComponentBus.h>
|
||||
#include <CoreLights/LightDelegateInterface.h>
|
||||
|
||||
@@ -40,6 +41,8 @@ namespace AZ
|
||||
LightDelegateBase(EntityId entityId, bool isVisible);
|
||||
virtual ~LightDelegateBase();
|
||||
|
||||
void SetConfig(const AreaLightComponentConfig* config) override;
|
||||
|
||||
// LightDelegateInterface overrides...
|
||||
void SetChroma(const AZ::Color& chroma) override;
|
||||
void SetIntensity(float intensity) override;
|
||||
@@ -66,6 +69,7 @@ namespace AZ
|
||||
|
||||
// Trivial getters
|
||||
FeatureProcessorType* GetFeatureProcessor() const { return m_featureProcessor; };
|
||||
const AreaLightComponentConfig* GetConfig() const { return m_componentConfig; };
|
||||
typename FeatureProcessorType::LightHandle GetLightHandle() const { return m_lightHandle; };
|
||||
const AZ::Transform& GetTransform() const { return m_transform; };
|
||||
bool GetShuttersEnabled() { return m_shuttersEnabled; };
|
||||
@@ -81,6 +85,7 @@ namespace AZ
|
||||
private:
|
||||
FeatureProcessorType* m_featureProcessor = nullptr;
|
||||
typename FeatureProcessorType::LightHandle m_lightHandle;
|
||||
const AreaLightComponentConfig* m_componentConfig = nullptr;
|
||||
|
||||
LmbrCentral::ShapeComponentRequests* m_shapeBus;
|
||||
AZ::Transform m_transform;
|
||||
|
||||
@@ -59,6 +59,12 @@ namespace AZ
|
||||
m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FeatureProcessorType>
|
||||
void LightDelegateBase<FeatureProcessorType>::SetConfig(const AreaLightComponentConfig* config)
|
||||
{
|
||||
m_componentConfig = config;
|
||||
}
|
||||
|
||||
template <typename FeatureProcessorType>
|
||||
void LightDelegateBase<FeatureProcessorType>::SetChroma(const AZ::Color& color)
|
||||
|
||||
@@ -33,6 +33,9 @@ namespace AZ
|
||||
{
|
||||
public:
|
||||
virtual ~LightDelegateInterface() {};
|
||||
|
||||
//! Sets the area light component config so delegates don't have to cache the same data locally.
|
||||
virtual void SetConfig(const AreaLightComponentConfig* config) = 0;
|
||||
//! Sets the color of the light independent of light intensity. The color is a mask on the total light intensity.
|
||||
virtual void SetChroma(const AZ::Color& chroma) = 0;
|
||||
//! Sets the light intensity
|
||||
|
||||
+30
-5
@@ -44,15 +44,40 @@ namespace AZ::Render
|
||||
{
|
||||
GetFeatureProcessor()->SetConeAngles(GetLightHandle(), DegToRad(innerAngleDegrees), DegToRad(outerAngleDegrees));
|
||||
}
|
||||
|
||||
void SimpleSpotLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
|
||||
void SimpleSpotLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& /*color*/, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
debugDisplay.SetColor(color);
|
||||
float innerRadians = DegToRad(GetConfig()->m_innerShutterAngleDegrees);
|
||||
float outerRadians = DegToRad(GetConfig()->m_outerShutterAngleDegrees);
|
||||
float radius = GetConfig()->m_attenuationRadius;
|
||||
|
||||
// Draw a cone for the cone angle and attenuation radius
|
||||
debugDisplay.DrawCone(transform.GetTranslation(), transform.GetBasisX(), CalculateAttenuationRadius(AreaLightComponentConfig::CutoffIntensity), false);
|
||||
// Draw a cone using the cone angle and attenuation radius
|
||||
innerRadians = GetMin(innerRadians, outerRadians);
|
||||
float coneRadiusInner = sin(innerRadians) * radius;
|
||||
float coneHeightInner = cos(innerRadians) * radius;
|
||||
float coneRadiusOuter = sin(outerRadians) * radius;
|
||||
float coneHeightOuter = cos(outerRadians) * radius;
|
||||
|
||||
debugDisplay.PushMatrix(transform);
|
||||
|
||||
auto DrawCone = [&debugDisplay](uint32_t numRadiusLines, float radius, float height, float brightness)
|
||||
{
|
||||
debugDisplay.SetColor(Color(brightness, brightness, brightness, 1.0f));
|
||||
debugDisplay.DrawWireDisk(Vector3(0.0, 0.0, height), Vector3::CreateAxisZ(), radius);
|
||||
|
||||
for (uint32_t i = 0; i < numRadiusLines; ++i)
|
||||
{
|
||||
float radiusLineAngle = float(i) / numRadiusLines * Constants::TwoPi;
|
||||
debugDisplay.DrawLine(Vector3::CreateZero(), Vector3(cos(radiusLineAngle) * radius, sin(radiusLineAngle) * radius, height));
|
||||
}
|
||||
};
|
||||
|
||||
DrawCone(16, coneRadiusInner, coneHeightInner, 1.0f);
|
||||
DrawCone(16, coneRadiusOuter, coneHeightOuter, 0.65f);
|
||||
|
||||
debugDisplay.PopMatrix();
|
||||
}
|
||||
}
|
||||
} // namespace AZ::Render
|
||||
|
||||
+3
-1
@@ -25,6 +25,8 @@ namespace AZ
|
||||
class SimpleSpotLightDelegate final
|
||||
: public LightDelegateBase<SimpleSpotLightFeatureProcessorInterface>
|
||||
{
|
||||
using Base = LightDelegateBase<SimpleSpotLightFeatureProcessorInterface>;
|
||||
|
||||
public:
|
||||
SimpleSpotLightDelegate(EntityId entityId, bool isVisible);
|
||||
|
||||
@@ -34,9 +36,9 @@ namespace AZ
|
||||
float GetSurfaceArea() const override;
|
||||
float GetEffectiveSolidAngle() const override { return PhotometricValue::DirectionalEffectiveSteradians; }
|
||||
void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) override;
|
||||
|
||||
private:
|
||||
virtual void HandleShapeChanged();
|
||||
|
||||
};
|
||||
|
||||
} // namespace Render
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ namespace AZ
|
||||
struct ThumbnailRendererData final
|
||||
{
|
||||
static constexpr const char* LightingPresetPath = "lightingpresets/thumbnail.lightingpreset.azasset";
|
||||
static constexpr const char* DefaultModelPath = "materialeditor/viewportmodels/quadsphere.azmodel";
|
||||
static constexpr const char* DefaultModelPath = "models/sphere.azmodel";
|
||||
static constexpr const char* DefaultMaterialPath = "materials/basic_grey.azmaterial";
|
||||
|
||||
RPI::ScenePtr m_scene;
|
||||
|
||||
@@ -519,8 +519,8 @@ void CAtomShimRenderAuxGeom::DrawQuad(float width, float height, const Matrix34&
|
||||
if (auto auxGeom = AZ::RPI::AuxGeomFeatureProcessorInterface::GetDrawQueueForScene(defaultScene))
|
||||
{
|
||||
AZ::RPI::AuxGeomDraw::DrawStyle drawStyle = drawShaded ? AZ::RPI::AuxGeomDraw::DrawStyle::Shaded : AZ::RPI::AuxGeomDraw::DrawStyle::Solid;
|
||||
AZ::Transform transform = LYTransformToAZTransform(matWorld);
|
||||
auxGeom->DrawQuad(width, height, transform, LYColorBToAZColor(col), drawStyle, m_drawArgs.m_depthTest);
|
||||
AZ::Matrix3x4 local2World = LYTransformToAZMatrix3x4(matWorld);
|
||||
auxGeom->DrawQuad(width, height, local2World, LYColorBToAZColor(col), drawStyle, m_drawArgs.m_depthTest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,12 +68,6 @@ ly_add_target(
|
||||
)
|
||||
|
||||
if (PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
|
||||
find_package(OpenGL QUIET REQUIRED)
|
||||
# Imported targets (like OpenGL::GL) are scoped to a directory. Add a
|
||||
# a global scope
|
||||
add_library(3rdParty::OpenGLInterface INTERFACE IMPORTED GLOBAL)
|
||||
target_link_libraries(3rdParty::OpenGLInterface INTERFACE OpenGL::GL)
|
||||
|
||||
ly_add_target(
|
||||
NAME EMotionFX.Editor.Static STATIC
|
||||
|
||||
@@ -131,8 +131,14 @@ namespace RenderGL
|
||||
|
||||
void GLRenderUtil::Validate()
|
||||
{
|
||||
mLineShader->Validate();
|
||||
mMeshShader->Validate();
|
||||
if (mLineShader)
|
||||
{
|
||||
mLineShader->Validate();
|
||||
}
|
||||
if (mMeshShader)
|
||||
{
|
||||
mMeshShader->Validate();
|
||||
}
|
||||
}
|
||||
|
||||
// destroy the allocated memory
|
||||
|
||||
@@ -116,12 +116,12 @@ namespace RenderGL
|
||||
}
|
||||
|
||||
|
||||
bool GLSLShader::CompileShader(const GLenum type, unsigned int* outShader, const char* filename)
|
||||
bool GLSLShader::CompileShader(const GLenum type, unsigned int* outShader, AZ::IO::PathView filename)
|
||||
{
|
||||
QFile file(filename);
|
||||
QFile file(QString::fromUtf8(filename.Native().data(), aznumeric_caster(filename.Native().size())));
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "[GLSL] Failed to open shader file '%s'.", filename);
|
||||
AZ_Error("EMotionFX", false, "[GLSL] Failed to open shader file '%.*s'.", AZ_STRING_ARG(filename.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace RenderGL
|
||||
|
||||
if (success == false)
|
||||
{
|
||||
MCore::LogError("[GLSL] Failed to compile shader '%s'.", filename);
|
||||
MCore::LogError("[GLSL] Failed to compile shader '%.*s'.", AZ_STRING_ARG(filename.Native()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// Init
|
||||
bool GLSLShader::Init(const char* vFile, const char* pFile, MCore::Array<AZStd::string>& defines)
|
||||
bool GLSLShader::Init(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines)
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
/*const char* args[] = { "unroll all",
|
||||
@@ -225,24 +225,24 @@ namespace RenderGL
|
||||
glUseProgram(0);
|
||||
|
||||
// compile shaders
|
||||
if (vFile && CompileShader(GL_VERTEX_SHADER, &mVertexShader, vFile) == false)
|
||||
if (!vertexFileName.empty() && CompileShader(GL_VERTEX_SHADER, &mVertexShader, vertexFileName) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pFile && CompileShader(GL_FRAGMENT_SHADER, &mPixelShader, pFile) == false)
|
||||
if (!pixelFileName.empty() && CompileShader(GL_FRAGMENT_SHADER, &mPixelShader, pixelFileName) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// create program
|
||||
mProgram = glCreateProgram();
|
||||
if (vFile)
|
||||
if (!vertexFileName.empty())
|
||||
{
|
||||
glAttachShader(mProgram, mVertexShader);
|
||||
}
|
||||
|
||||
if (pFile)
|
||||
if (!pixelFileName.empty())
|
||||
{
|
||||
glAttachShader(mProgram, mPixelShader);
|
||||
}
|
||||
@@ -256,7 +256,7 @@ namespace RenderGL
|
||||
|
||||
if (!success)
|
||||
{
|
||||
MCore::LogInfo("[OpenGL] Failed to link shaders '%s' and '%s' ", vFile, pFile);
|
||||
MCore::LogInfo("[OpenGL] Failed to link shaders '%.*s' and '%.*s' ", AZ_STRING_ARG(vertexFileName.Native()), AZ_STRING_ARG(pixelFileName.Native()));
|
||||
InfoLog(mProgram, &QOpenGLExtraFunctions::glGetProgramInfoLog);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define __RENDERGL_GLSLSHADER_H
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include "Shader.h"
|
||||
|
||||
// include OpenGL
|
||||
@@ -45,7 +46,7 @@ namespace RenderGL
|
||||
MCORE_INLINE unsigned int GetProgram() const { return mProgram; }
|
||||
bool CheckIfIsDefined(const char* attributeName);
|
||||
|
||||
bool Init(const char* vertexFileName, const char* pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
bool Init(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
void SetAttribute(const char* name, uint32 dim, uint32 type, uint32 stride, size_t offset) override;
|
||||
|
||||
void SetUniform(const char* name, float value) override;
|
||||
@@ -81,11 +82,11 @@ namespace RenderGL
|
||||
ShaderParameter* FindAttribute(const char* name);
|
||||
ShaderParameter* FindUniform(const char* name);
|
||||
|
||||
bool CompileShader(const GLenum type, unsigned int* outShader, const char* filename);
|
||||
bool CompileShader(const GLenum type, unsigned int* outShader, AZ::IO::PathView filename);
|
||||
template<class T>
|
||||
void InfoLog(GLuint object, T func);
|
||||
|
||||
AZStd::string mFileName;
|
||||
AZ::IO::Path mFileName;
|
||||
|
||||
MCore::Array<uint32> mActivatedAttribs;
|
||||
MCore::Array<uint32> mActivatedTextures;
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to initialize the graphics system
|
||||
bool GraphicsManager::Init(const char* shaderPath)
|
||||
bool GraphicsManager::Init(AZ::IO::PathView shaderPath)
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
@@ -364,7 +364,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to load a texture
|
||||
Texture* GraphicsManager::LoadTexture([[maybe_unused]] const char* filename, [[maybe_unused]] bool createMipMaps)
|
||||
Texture* GraphicsManager::LoadTexture([[maybe_unused]] AZ::IO::PathView filename, [[maybe_unused]] bool createMipMaps)
|
||||
{
|
||||
//Texture Library is no longer used
|
||||
//temporarily blank
|
||||
@@ -373,19 +373,19 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to load a texture
|
||||
Texture* GraphicsManager::LoadTexture(const char* filename)
|
||||
Texture* GraphicsManager::LoadTexture(AZ::IO::PathView filename)
|
||||
{
|
||||
return LoadTexture(filename, mCreateMipMaps);
|
||||
}
|
||||
|
||||
|
||||
// LoadPostProcessShader
|
||||
PostProcessShader* GraphicsManager::LoadPostProcessShader(const char* cFileName)
|
||||
PostProcessShader* GraphicsManager::LoadPostProcessShader(AZ::IO::PathView cFileName)
|
||||
{
|
||||
AZStd::string filename = mShaderPath + AZStd::string(cFileName);
|
||||
AZ::IO::PathView filename = mShaderPath / cFileName;
|
||||
|
||||
// check if the shader is already in the cache
|
||||
Shader* s = mShaderCache.FindShader(filename.c_str());
|
||||
Shader* s = mShaderCache.FindShader(filename.Native());
|
||||
if (s)
|
||||
{
|
||||
return (PostProcessShader*)s;
|
||||
@@ -393,19 +393,19 @@ namespace RenderGL
|
||||
|
||||
// load the shader from disk
|
||||
PostProcessShader* shader = new PostProcessShader();
|
||||
if (!shader->Init(filename.c_str()))
|
||||
if (!shader->Init(filename))
|
||||
{
|
||||
delete shader;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mShaderCache.AddShader(filename.c_str(), shader);
|
||||
mShaderCache.AddShader(filename.Native(), shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
// LoadShader
|
||||
GLSLShader* GraphicsManager::LoadShader(const char* vertexFileName, const char* pixelFileName)
|
||||
GLSLShader* GraphicsManager::LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName)
|
||||
{
|
||||
MCore::Array<AZStd::string> defines;
|
||||
return LoadShader(vertexFileName, pixelFileName, defines);
|
||||
@@ -413,34 +413,21 @@ namespace RenderGL
|
||||
|
||||
|
||||
// LoadShader
|
||||
GLSLShader* GraphicsManager::LoadShader(const char* vFile, const char* pFile, MCore::Array<AZStd::string>& defines)
|
||||
GLSLShader* GraphicsManager::LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines)
|
||||
{
|
||||
AZStd::string vStr;
|
||||
AZStd::string pStr;
|
||||
|
||||
if (vFile)
|
||||
{
|
||||
vStr = AZStd::string::format("%s%s", mShaderPath.c_str(), vFile);
|
||||
}
|
||||
|
||||
if (pFile)
|
||||
{
|
||||
pStr = AZStd::string::format("%s%s", mShaderPath.c_str(), pFile);
|
||||
}
|
||||
const AZ::IO::Path vertexPath {vertexFileName.empty() ? AZ::IO::Path{} : mShaderPath / vertexFileName};
|
||||
const AZ::IO::Path pixelPath {pixelFileName.empty() ? AZ::IO::Path{} : mShaderPath / pixelFileName};
|
||||
|
||||
// construct the lookup string for the shader cache
|
||||
AZStd::string dStr;
|
||||
AZStd::string cacheLookupStr = vertexPath.Native() + pixelPath.Native();
|
||||
const uint32 numDefines = defines.GetLength();
|
||||
for (uint32 n = 0; n < numDefines; n++)
|
||||
{
|
||||
dStr += AZStd::string::format("#%s", defines[n].c_str());
|
||||
cacheLookupStr += AZStd::string::format("#%s", defines[n].c_str());
|
||||
}
|
||||
|
||||
AZStd::string cStr;
|
||||
cStr = AZStd::string::format("%s%s%s", vStr.c_str(), pStr.c_str(), dStr.c_str());
|
||||
|
||||
// check if the shader is already in the cache
|
||||
Shader* cShader = mShaderCache.FindShader(cStr.c_str());
|
||||
Shader* cShader = mShaderCache.FindShader(cacheLookupStr);
|
||||
if (cShader)
|
||||
{
|
||||
return (GLSLShader*)cShader;
|
||||
@@ -448,13 +435,13 @@ namespace RenderGL
|
||||
|
||||
// load the shader from disk
|
||||
GLSLShader* shader = new GLSLShader();
|
||||
if (!shader->Init(vFile ? vStr.c_str() : nullptr, pFile ? pStr.c_str() : nullptr, defines))
|
||||
if (!shader->Init(vertexPath, pixelPath, defines))
|
||||
{
|
||||
delete shader;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mShaderCache.AddShader(cStr.c_str(), shader);
|
||||
mShaderCache.AddShader(cacheLookupStr, shader);
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef __RENDERGL_GRAPHICSMANAGER__H
|
||||
#define __RENDERGL_GRAPHICSMANAGER__H
|
||||
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <MCore/Source/StandardHeaders.h>
|
||||
#include <MCore/Source/Vector.h>
|
||||
#include <MCore/Source/Color.h>
|
||||
@@ -57,21 +58,21 @@ namespace RenderGL
|
||||
const char* GetDeviceName();
|
||||
const char* GetDeviceVendor();
|
||||
MCORE_INLINE RenderTexture* GetRenderTexture() { return mRenderTexture; }
|
||||
MCORE_INLINE const char* GetShaderPath() const { return mShaderPath.c_str(); }
|
||||
MCORE_INLINE AZ::IO::PathView GetShaderPath() const { return mShaderPath; }
|
||||
MCORE_INLINE TextureCache* GetTextureCache() { return &mTextureCache; }
|
||||
|
||||
bool Init(const char* shaderPath = "Shaders/");
|
||||
bool Init(AZ::IO::PathView shaderPath = "Shaders");
|
||||
|
||||
bool GetIsPostProcessingEnabled() const { return mPostProcessing; }
|
||||
PostProcessShader* LoadPostProcessShader(const char* filename);
|
||||
GLSLShader* LoadShader(const char* vertexFileName, const char* pixelFileName);
|
||||
GLSLShader* LoadShader(const char* vertexFileName, const char* pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
PostProcessShader* LoadPostProcessShader(AZ::IO::PathView filename);
|
||||
GLSLShader* LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName);
|
||||
GLSLShader* LoadShader(AZ::IO::PathView vertexFileName, AZ::IO::PathView pixelFileName, MCore::Array<AZStd::string>& defines);
|
||||
|
||||
MCORE_INLINE void SetGBuffer(GBuffer* gBuffer) { mGBuffer = gBuffer; }
|
||||
MCORE_INLINE GBuffer* GetGBuffer() { return mGBuffer; }
|
||||
|
||||
Texture* LoadTexture(const char* filename, bool createMipMaps);
|
||||
Texture* LoadTexture(const char* filename);
|
||||
Texture* LoadTexture(AZ::IO::PathView filename, bool createMipMaps);
|
||||
Texture* LoadTexture(AZ::IO::PathView filename);
|
||||
|
||||
void SetCreateMipMaps(bool createMipMaps) { mCreateMipMaps = createMipMaps; }
|
||||
MCORE_INLINE bool GetCreateMipMaps() const { return mCreateMipMaps; }
|
||||
@@ -96,7 +97,7 @@ namespace RenderGL
|
||||
|
||||
void SetShader(Shader* shader);
|
||||
MCORE_INLINE void SetRenderTexture(RenderTexture* texture) { mRenderTexture = texture; }
|
||||
MCORE_INLINE void SetShaderPath(const char* shaderPath) { mShaderPath = shaderPath; }
|
||||
MCORE_INLINE void SetShaderPath(AZ::IO::PathView shaderPath) { mShaderPath = shaderPath; }
|
||||
|
||||
MCORE_INLINE void SetBloomEnabled(bool enabled) { mBloomEnabled = enabled; }
|
||||
MCORE_INLINE void SetBloomThreshold(float threshold) { mBloomThreshold = threshold; }
|
||||
@@ -154,7 +155,7 @@ namespace RenderGL
|
||||
MCommon::Camera* mCamera; /**< The camera used for rendering. */
|
||||
|
||||
ShaderCache mShaderCache; /**< The shader manager used to load and manage vertex and pixel shaders. */
|
||||
AZStd::string mShaderPath; /**< The absolute path to the directory where the shaders are located. This string will be added as prefix to each shader file the user tries to load. */
|
||||
AZ::IO::Path mShaderPath; /**< The absolute path to the directory where the shaders are located. This string will be added as prefix to each shader file the user tries to load. */
|
||||
MCore::RGBAColor mClearColor; /**< The scene background color. */
|
||||
MCore::RGBAColor mGradientSourceColor; /**< The background gradient source color. */
|
||||
MCore::RGBAColor mGradientTargetColor; /**< The background gradient target color. */
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include "PostProcessShader.h"
|
||||
#include "GraphicsManager.h"
|
||||
|
||||
@@ -82,7 +83,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// Init
|
||||
bool PostProcessShader::Init(const char* filename)
|
||||
bool PostProcessShader::Init(AZ::IO::PathView filename)
|
||||
{
|
||||
MCore::Array<AZStd::string> defines;
|
||||
return GLSLShader::Init(nullptr, filename, defines);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef __RENDERGL_POSTPROCESS_SHADER_H
|
||||
#define __RENDERGL_POSTPROCESS_SHADER_H
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include "GLSLShader.h"
|
||||
#include "RenderTexture.h"
|
||||
|
||||
@@ -34,7 +35,7 @@ namespace RenderGL
|
||||
|
||||
void Deactivate() override;
|
||||
|
||||
bool Init(const char* filename);
|
||||
bool Init(AZ::IO::PathView filename);
|
||||
void Render();
|
||||
|
||||
private:
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace RenderGL
|
||||
|
||||
|
||||
// add the shader to the cache (assume there are no duplicate names)
|
||||
void ShaderCache::AddShader(const char* filename, Shader* shader)
|
||||
void ShaderCache::AddShader(AZStd::string_view filename, Shader* shader)
|
||||
{
|
||||
mEntries.AddEmpty();
|
||||
mEntries.GetLast().mName = filename;
|
||||
@@ -57,12 +57,12 @@ namespace RenderGL
|
||||
|
||||
|
||||
// try to locate a shader based on its name
|
||||
Shader* ShaderCache::FindShader(const char* filename) const
|
||||
Shader* ShaderCache::FindShader(AZStd::string_view filename) const
|
||||
{
|
||||
const uint32 numEntries = mEntries.GetLength();
|
||||
for (uint32 i = 0; i < numEntries; ++i)
|
||||
{
|
||||
if (AzFramework::StringFunc::Equal(mEntries[i].mName.c_str(), filename, false /* no case */)) // non-case-sensitive name compare
|
||||
if (AzFramework::StringFunc::Equal(mEntries[i].mName, filename, false /* no case */)) // non-case-sensitive name compare
|
||||
{
|
||||
return mEntries[i].mShader;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace RenderGL
|
||||
~ShaderCache(); // automatically calls Release
|
||||
|
||||
void Release();
|
||||
void AddShader(const char* filename, Shader* shader);
|
||||
Shader* FindShader(const char* filename) const;
|
||||
void AddShader(AZStd::string_view filename, Shader* shader);
|
||||
Shader* FindShader(AZStd::string_view filename) const;
|
||||
bool CheckIfHasShader(Shader* shader) const;
|
||||
|
||||
private:
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ namespace EMStudio
|
||||
|
||||
// create graphics manager and initialize it
|
||||
mGraphicsManager = new RenderGL::GraphicsManager();
|
||||
if (mGraphicsManager->Init(shaderPath.c_str()) == false)
|
||||
if (mGraphicsManager->Init(shaderPath) == false)
|
||||
{
|
||||
MCore::LogError("Could not initialize OpenGL graphics manager.");
|
||||
return false;
|
||||
|
||||
@@ -13,10 +13,4 @@
|
||||
# based on the active platform
|
||||
# NOTE: functions in cmake are global, therefore adding functions to this file
|
||||
# is being avoided to prevent overriding functions declared in other targets platfrom
|
||||
# specific cmake files
|
||||
|
||||
target_compile_definitions(3rdParty::OpenGLInterface
|
||||
INTERFACE
|
||||
# MacOS 10.14 deprecates OpenGL. This silences the warnings for now.
|
||||
GL_SILENCE_DEPRECATION
|
||||
)
|
||||
# specific cmake files
|
||||
@@ -823,20 +823,37 @@ void CAnimSequence::SetId(uint32 newId)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CAnimSequence::Reflect(AZ::SerializeContext* serializeContext)
|
||||
static bool AnimSequenceVersionConverter(
|
||||
AZ::SerializeContext& serializeContext,
|
||||
AZ::SerializeContext::DataElementNode& rootElement)
|
||||
{
|
||||
serializeContext->Class<CAnimSequence>()
|
||||
->Version(4)
|
||||
->Field("Name", &CAnimSequence::m_name)
|
||||
->Field("SequenceEntityId", &CAnimSequence::m_sequenceEntityId)
|
||||
->Field("Flags", &CAnimSequence::m_flags)
|
||||
->Field("TimeRange", &CAnimSequence::m_timeRange)
|
||||
->Field("ID", &CAnimSequence::m_id)
|
||||
->Field("Nodes", &CAnimSequence::m_nodes)
|
||||
->Field("SequenceType", &CAnimSequence::m_sequenceType)
|
||||
->Field("Events", &CAnimSequence::m_events)
|
||||
->Field("Expanded", &CAnimSequence::m_expanded)
|
||||
->Field("ActiveDirectorNodeId", &CAnimSequence::m_activeDirectorNodeId);
|
||||
if (rootElement.GetVersion() < 5)
|
||||
{
|
||||
rootElement.AddElement(serializeContext, "BaseClass1", azrtti_typeid<IAnimSequence>());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAnimSequence::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
IAnimSequence::Reflect(context);
|
||||
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context); serializeContext != nullptr)
|
||||
{
|
||||
serializeContext->Class<CAnimSequence, IAnimSequence>()
|
||||
->Version(IAnimSequence::kSequenceVersion, &AnimSequenceVersionConverter)
|
||||
->Field("Name", &CAnimSequence::m_name)
|
||||
->Field("SequenceEntityId", &CAnimSequence::m_sequenceEntityId)
|
||||
->Field("Flags", &CAnimSequence::m_flags)
|
||||
->Field("TimeRange", &CAnimSequence::m_timeRange)
|
||||
->Field("ID", &CAnimSequence::m_id)
|
||||
->Field("Nodes", &CAnimSequence::m_nodes)
|
||||
->Field("SequenceType", &CAnimSequence::m_sequenceType)
|
||||
->Field("Events", &CAnimSequence::m_events)
|
||||
->Field("Expanded", &CAnimSequence::m_expanded)
|
||||
->Field("ActiveDirectorNodeId", &CAnimSequence::m_activeDirectorNodeId);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -154,7 +154,7 @@ public:
|
||||
return m_nextTrackId++;
|
||||
}
|
||||
|
||||
static void Reflect(AZ::SerializeContext* serializeContext);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
private:
|
||||
void ComputeTimeRange();
|
||||
|
||||
+9
-81
@@ -1,84 +1,12 @@
|
||||
-- When you see an option that does not have a platform preceeding it, that is the default
|
||||
-- value for anything not specificly set per platform. So if remote_filesystem=0 and you have
|
||||
-- ios_remote_file_system=1 then remote filesystem will be off for all platforms except ios
|
||||
-- Any of the settings in this file can be prefixed with a platform name:
|
||||
-- android, ios, mac, linux, windows, etc...
|
||||
-- or left unprefixed, to set all platforms not specified. The rules apply in the order they're declared
|
||||
; This file is deprecated and is only use currently for setting the path when running O3DE in an engine-centric manner
|
||||
; By engine-centric, what is meant is using CMake to configure from the <engine-root> directory and passing in the LY_PROJECTS value
|
||||
|
||||
project_path=AutomatedTesting
|
||||
|
||||
-- remote_filesystem - enable Virtual File System (VFS)
|
||||
-- This feature allows a remote instance of the game to run off assets
|
||||
-- on the asset processor computers cache instead of deploying them the remote device
|
||||
-- By default it is off and can be overridden for any platform
|
||||
remote_filesystem=0
|
||||
provo_remote_filesystem=0
|
||||
android_remote_filesystem=0
|
||||
ios_remote_filesystem=0
|
||||
mac_remote_filesystem=0
|
||||
|
||||
-- What type of assets are we going to load?
|
||||
-- We need to know this before we establish VFS because different platform assets
|
||||
-- are stored in different root folders in the cache. These correspond to the names
|
||||
-- In the asset processor config file. This value also controls what config file is read
|
||||
-- when you read system_xxxx_xxxx.cfg (for example, system_windows_pc.cfg or system_android_es3.cfg)
|
||||
-- by default, pc assets (in the 'pc' folder) are used, with RC being fed 'pc' as the platform
|
||||
-- by default on console we use the default assets=pc for better iteration times
|
||||
-- we should turn on console specific assets only when in release and/or testing assets and/or loading performance
|
||||
-- that way most people will not need to have 3 different caches taking up disk space
|
||||
assets = pc
|
||||
-- provo_assets = provo
|
||||
-- salem_assets = salem
|
||||
-- jasper_assets = jasper
|
||||
android_assets = es3
|
||||
ios_assets = ios
|
||||
mac_assets = osx_gl
|
||||
|
||||
-- Add the IP address of your console to the allowed list that will connect to the asset processor here
|
||||
-- You can list addresses or CIDR's. CIDR's are helpful if you are using DHCP. A CIDR looks like an ip address with
|
||||
-- a /n on the end means how many bits are significant. 8bits.8bits.8bits.8bits = /32
|
||||
-- Example: 192.168.1.3
|
||||
-- Example: 192.168.1.3, 192.168.1.15
|
||||
-- Example: 192.168.1.0/24 will allow any address starting with 192.168.1.
|
||||
-- Example: 192.168.0.0/16 will allow any address starting with 192.168.
|
||||
-- Example: 192.168.0.0/8 will allow any address starting with 192.
|
||||
-- allowed_list =
|
||||
|
||||
-- IP address and optionally port of the asset processor.
|
||||
-- Set your PC IP here: (and uncomment the next line)
|
||||
-- If you are running your asset processor on a windows machine you
|
||||
-- can find out your ip address by opening a cmd prompt and typing in ipconfig
|
||||
-- remote_ip = 127.0.0.1
|
||||
-- remote_port = 45643
|
||||
|
||||
-- Which way do you want to connect the asset processor to the game: 1=game connects to AP "connect", 0=AP connects to game "listen"
|
||||
-- Note: android and IOS over USB port forwarding may need to listen instead of connect
|
||||
connect_to_remote=0
|
||||
windows_connect_to_remote=1
|
||||
provo_connect_to_remote=1
|
||||
salem_connect_to_remote=0
|
||||
jasper_connect_to_remote=0
|
||||
android_connect_to_remote=0
|
||||
ios_connect_to_remote=0
|
||||
mac_connect_to_remote=0
|
||||
|
||||
-- Should we tell the game to wait and not proceed unless we have a connection to the AP or
|
||||
-- do we allow it to continue to try to connect in the background without waiting
|
||||
-- Note: Certain options REQUIRE that we do not proceed unless we have a connection, and will override this option to 1 when set
|
||||
-- Since remote_filesystem=1 requires a connection to proceed it will override our option to 1
|
||||
wait_for_connect=0
|
||||
provo_wait_for_connect=0
|
||||
salem_wait_for_connect=0
|
||||
jasper_wait_for_connect=0
|
||||
windows_wait_for_connect=1
|
||||
android_wait_for_connect=0
|
||||
ios_wait_for_connect=0
|
||||
mac_wait_for_connect=0
|
||||
|
||||
-- How long applications should wait while attempting to connect to an already launched AP(in seconds)
|
||||
-- connect_ap_timeout=3
|
||||
|
||||
-- How long application should wait when launching the AP and wait for the AP to connect back to it(in seconds)
|
||||
-- This time is dependent on Machine load as well as how long it takes for the new AP instance to initialize
|
||||
-- A debug AP takes longer to start up than a profile AP
|
||||
-- launch_ap_timeout=15
|
||||
; The Asset Processor Specific settings are now the <engine-root>/Engine/Registry/bootstrap.setreg settings
|
||||
; The Engine specific settings can be overridden in order of least precedence to most
|
||||
; 1. Override the settings in a "<gem-root>/Registry/*.setreg(patch)" file (Shared per Gem Settings)
|
||||
; 2. Override the settings in a "<project-root>/Registry/*.setreg(patch)" file (Shared per Project Settings)
|
||||
; 3. Override the settings in a "<project-root>/Registry/*.setreg(patch)" file (User per Project Settings)
|
||||
; 4. Override the settings in a "~/.o3de/Registry/*.setreg(patch)" file (User Global Settings)
|
||||
; Where "~" is %USERPROFILE% on Windows and $HOME on Unix like platforms
|
||||
|
||||
@@ -116,10 +116,6 @@ function(ly_add_external_target)
|
||||
# Setting BASE_PATH variable in the parent scope to allow for the Find<3rdParty>.cmake scripts to use them
|
||||
set(BASE_PATH ${BASE_PATH} PARENT_SCOPE)
|
||||
|
||||
if(NOT EXISTS ${BASE_PATH})
|
||||
message(FATAL_ERROR "Cannot find 3rdParty library ${ly_add_external_target_NAME} on path ${BASE_PATH}")
|
||||
endif()
|
||||
|
||||
add_library(3rdParty::${NAME_WITH_NAMESPACE} INTERFACE IMPORTED GLOBAL)
|
||||
|
||||
if(ly_add_external_target_INCLUDE_DIRECTORIES)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
find_package(OpenGL)
|
||||
|
||||
ly_add_external_target(
|
||||
NAME OpenGLInterface
|
||||
VERSION ""
|
||||
BUILD_DEPENDENCIES
|
||||
OpenGL::GL
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
# MacOS 10.14 deprecates OpenGL. This silences the warnings for now.
|
||||
set(OPENGLINTERFACE_COMPILE_DEFINITIONS GL_SILENCE_DEPRECATION)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user