Merge branch 'upstream/development' into LYN-8514_AutomatedReviewServerLogChecks

This commit is contained in:
Gene Walters
2021-11-30 14:34:42 -08:00
595 changed files with 16165 additions and 11658 deletions
@@ -45,6 +45,7 @@
#include <AzCore/Module/Module.h>
#include <AzCore/Module/ModuleManager.h>
#include <AzCore/IO/Path/PathReflect.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Driller/Driller.h>
@@ -1547,7 +1548,7 @@ namespace AZ
// reflect name dictionary.
Name::Reflect(context);
// reflect path
IO::PathReflection::Reflect(context);
IO::PathReflect(context);
// reflect the SettingsRegistryInterface, SettignsRegistryImpl and the global Settings Registry
// instance (AZ::SettingsRegistry::Get()) into the Behavior Context
@@ -32,7 +32,16 @@ namespace AZ
template <typename BASE_TYPE, ThreadSafety THREAD_SAFETY>
inline void ConsoleDataWrapper<BASE_TYPE, THREAD_SAFETY>::operator =(const BASE_TYPE& rhs)
{
const BASE_TYPE currentValue = this->m_value;
// Do the value assignment outside new value check.
// Client code can supply a type for m_value that overrides the operator= function and trigger side effects
// in the operator= function body. Doing the assignment outside the value change check avoids those side
// effects not being triggered because AzCore believes the value wouldn't change.
this->m_value = rhs;
if (currentValue != rhs)
{
InvokeCallback();
}
}
template <typename BASE_TYPE, ThreadSafety THREAD_SAFETY>
@@ -50,13 +50,4 @@ namespace AZ::IO
const PathIterator<Path>& rhs);
template bool operator!=<FixedMaxPath>(const PathIterator<FixedMaxPath>& lhs,
const PathIterator<FixedMaxPath>& rhs);
void PathReflection::Reflect(AZ::ReflectContext* context)
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<AZ::IO::Path>()
->Field("m_path", &AZ::IO::Path::m_path);
}
}
}
+3 -2
View File
@@ -78,7 +78,8 @@ namespace AZ::IO
// native format observers
//! Returns string_view stored within the PathView
constexpr AZStd::string_view Native() const noexcept;
constexpr const AZStd::string_view& Native() const noexcept;
constexpr AZStd::string_view& Native() noexcept;
//! Conversion operator to retrieve string_view stored within the PathView
constexpr explicit operator AZStd::string_view() const noexcept;
@@ -321,7 +322,6 @@ namespace AZ::IO
using const_iterator = const PathIterator<BasicPath>;
using iterator = const_iterator;
friend PathIterator<BasicPath>;
friend struct PathReflection;
// constructors and destructor
constexpr BasicPath() = default;
@@ -665,6 +665,7 @@ namespace AZ::IO
namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(AZ::IO::Path, "{88E0A40F-3085-4CAB-8B11-EF5A2659C71A}");
AZ_TYPE_INFO_SPECIALIZE(AZ::IO::FixedMaxPath, "{FA6CA49F-376A-417C-9767-DD50744DF203}");
}
namespace AZ::IO
@@ -101,7 +101,11 @@ namespace AZ::IO
}
// native format observers
constexpr auto PathView::Native() const noexcept -> AZStd::string_view
constexpr auto PathView::Native() const noexcept -> const AZStd::string_view&
{
return m_path;
}
constexpr auto PathView::Native() noexcept -> AZStd::string_view&
{
return m_path;
}
@@ -0,0 +1,77 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/functional.h>
namespace AZ::IO
{
template <typename PathType>
struct PathSerializer
: public SerializeContext::IDataSerializer
{
public:
/// Convert binary data to text
size_t DataToText(IO::GenericStream& in, IO::GenericStream& out, bool) override
{
PathType outPath;
outPath.Native().resize_no_construct(in.GetLength());
in.Read(outPath.Native().size(), outPath.Native().data());
return static_cast<size_t>(out.Write(outPath.Native().size(), outPath.Native().c_str()));
}
size_t TextToData(const char* text, unsigned int, IO::GenericStream& stream, bool) override
{
return static_cast<size_t>(stream.Write(strlen(text), reinterpret_cast<const void*>(text)));
}
size_t Save(const void* classPtr, IO::GenericStream& stream, bool) override
{
/// Save paths out using the PosixPathSeparator
PathType path(reinterpret_cast<const PathType*>(classPtr)->Native(), AZ::IO::PosixPathSeparator);
path.MakePreferred();
return static_cast<size_t>(stream.Write(path.Native().size(), path.c_str()));
}
bool Load(void* classPtr, IO::GenericStream& stream, unsigned int, bool) override
{
// Normalize the path load
auto path = reinterpret_cast<PathType*>(classPtr);
path->Native().resize_no_construct(stream.GetLength());
stream.Read(path->Native().size(), path->Native().data());
*path = path->LexicallyNormal();
return true;
}
bool CompareValueData(const void* lhs, const void* rhs) override
{
return SerializeContext::EqualityCompareHelper<Path>::CompareValues(lhs, rhs);
}
};
void PathReflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<SerializeContext*>(context); serializeContext != nullptr)
{
serializeContext->Class<Path>()
->Serializer(AZ::SerializeContext::IDataSerializerPtr{ new PathSerializer<Path>{},
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
;
serializeContext->Class<FixedMaxPath>()
->Serializer(AZ::SerializeContext::IDataSerializerPtr{ new PathSerializer<FixedMaxPath>{},
AZ::SerializeContext::IDataSerializer::CreateDefaultDeleteDeleter() })
;
}
}
}
@@ -8,4 +8,12 @@
#pragma once
#define STREAM_CACHE_DEFAULT 0
namespace AZ
{
class ReflectContext;
}
namespace AZ::IO
{
void PathReflect(AZ::ReflectContext* context);
}
@@ -57,11 +57,6 @@ namespace AZ::IO
// It depends on the path type
template <typename PathType>
class PathIterator;
struct PathReflection
{
static void Reflect(AZ::ReflectContext* context);
};
}
namespace AZStd
@@ -24,7 +24,7 @@
AZ_CVAR(float, cl_jobThreadsConcurrencyRatio, 0.6f, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system multiplier on the number of hw threads the machine creates at initialization");
AZ_CVAR(uint32_t, cl_jobThreadsNumReserved, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system number of hardware threads that are reserved for O3DE system threads");
AZ_CVAR(uint32_t, cl_jobThreadsMinNumber, 2, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system minimum number of worker threads to create after scaling the number of hw threads");
AZ_CVAR(uint32_t, cl_jobThreadsMinNumber, 3, nullptr, AZ::ConsoleFunctorFlags::Null, "Legacy Job system minimum number of worker threads to create after scaling the number of hw threads");
namespace AZ
{
@@ -351,7 +351,8 @@ namespace AZ
->Method("CreateFromMatrix3x3AndTranslation", &Matrix3x4::CreateFromMatrix3x3AndTranslation)
->Method("CreateScale", &Matrix3x4::CreateScale)
->Method("CreateDiagonal", &Matrix3x4::CreateDiagonal)
->Method("CreateTranslation", &Matrix3x4::CreateTranslation);
->Method("CreateTranslation", &Matrix3x4::CreateTranslation)
->Method("UnsafeCreateFromMatrix4x4", &Matrix3x4::UnsafeCreateFromMatrix4x4);
}
}
@@ -90,6 +90,9 @@ namespace AZ
//! Constructs from a Matrix3x3 and a translation.
static Matrix3x4 CreateFromMatrix3x3AndTranslation(const Matrix3x3& matrix3x3, const Vector3& translation);
//! Constructs from a Matrix4x4.
static Matrix3x4 UnsafeCreateFromMatrix4x4(const Matrix4x4& matrix4x4);
//! Constructs from a Transform.
static Matrix3x4 CreateFromTransform(const Transform& transform);
@@ -227,7 +230,7 @@ namespace AZ
Matrix3x4& operator+=(const Matrix3x4& rhs);
//! @}
//! Operator for matrix-matrix substraction.
//! Operator for matrix-matrix subtraction.
//! @{
[[nodiscard]] Matrix3x4 operator-(const Matrix3x4& rhs) const;
Matrix3x4& operator-=(const Matrix3x4& rhs);
@@ -266,6 +269,9 @@ namespace AZ
//! Post-multiplies the matrix by a vector, using only the 3x3 part of the matrix.
[[nodiscard]] Vector3 TransformVector(const Vector3& rhs) const;
//! Post-multiplies the matrix by a point, using the rotation and translation part of the matrix.
[[nodiscard]] Vector3 TransformPoint(const Vector3& rhs) const;
//! Gets the result of transposing the 3x3 part of the matrix, setting the translation part to zero.
[[nodiscard]] Matrix3x4 GetTranspose() const;
@@ -203,6 +203,16 @@ namespace AZ
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::UnsafeCreateFromMatrix4x4(const Matrix4x4& matrix4x4)
{
Matrix3x4 result;
result.SetRow(0, matrix4x4.GetRow(0));
result.SetRow(1, matrix4x4.GetRow(1));
result.SetRow(2, matrix4x4.GetRow(2));
return result;
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::CreateScale(const Vector3& scale)
{
return CreateDiagonal(scale);
@@ -609,6 +619,12 @@ namespace AZ
}
AZ_MATH_INLINE Vector3 Matrix3x4::TransformPoint(const Vector3& rhs) const
{
return Multiply3x3(rhs) + GetTranslation();
}
AZ_MATH_INLINE Matrix3x4 Matrix3x4::GetTranspose() const
{
Matrix3x4 result;
@@ -9,6 +9,7 @@
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ConsoleFunctor.h>
#include <AzCore/IO/ByteContainerStream.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/Settings/SettingsRegistryConsoleUtils.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/StringFunc/StringFunc.h>
@@ -36,7 +37,7 @@ namespace AZ::SettingsRegistryConsoleUtils
combinedKeyValueCommand.c_str());
AZ::Debug::Trace::Output("SettingsRegistry", setOutput.c_str());
}
};
}
static void ConsoleRemoveSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
{
@@ -57,7 +58,7 @@ namespace AZ::SettingsRegistryConsoleUtils
AZ::Debug::Trace::Output("SettingsRegistry", removeOutput.c_str());
}
}
};
}
static void ConsoleDumpSettingsRegistryValue(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
{
@@ -88,13 +89,39 @@ namespace AZ::SettingsRegistryConsoleUtils
}
AZ::Debug::Trace::Output("SettingsRegistry", outputString.c_str());
};
}
static void ConsoleDumpAllSettingsRegistryValues(SettingsRegistryInterface& settingsRegistry,
[[maybe_unused]] const ConsoleCommandContainer& commandArgs)
{
ConsoleDumpSettingsRegistryValue(settingsRegistry, { "" });
};
}
static void ConsoleMergeFileToSettingsRegistry(SettingsRegistryInterface& settingsRegistry, const ConsoleCommandContainer& commandArgs)
{
if (commandArgs.empty())
{
AZ_Error("SettingsRegistryConsoleUtils", false, "Command %s requires a <file path> argument to locate json file to merge",
SettingsRegistryMergeFile);
return;
}
auto commandArgumentsIter = commandArgs.begin();
// Extract the JSON pointer path from the argument list
AZStd::string_view filePath{ *commandArgumentsIter++ };
AZ::SettingsRegistryInterface::FixedValueString jsonAnchorPath;
AZ::StringFunc::Join(jsonAnchorPath, commandArgumentsIter, commandArgs.end(), ' ');
const auto mergeFormat = AZ::IO::PathView(filePath).Extension() != ".setregpatch" ? AZ::SettingsRegistryInterface::Format::JsonMergePatch : AZ::SettingsRegistryInterface::Format::JsonPatch;
if (settingsRegistry.MergeSettingsFile(filePath, mergeFormat, jsonAnchorPath))
{
const auto mergeFileOutput = AZ::SettingsRegistryInterface::FixedValueString::format(
R"(Merged json file "%*.s" anchored to json path "%s" into the global settings registry)" "\n",
AZ_STRING_ARG(filePath), jsonAnchorPath.c_str());
AZ::Debug::Trace::Output("SettingsRegistry", mergeFileOutput.c_str());
}
}
[[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole)
{
@@ -115,6 +142,11 @@ namespace AZ::SettingsRegistryConsoleUtils
resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryDumpAll,
R"(Dumps all values from the global settings registry)" "\n",
ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleDumpAllSettingsRegistryValues);
resultHandle.m_consoleFunctors.emplace_back(azConsole, SettingsRegistryMergeFile,
R"(Merges File into the global settings registry)" "\n"
R"(@param file-path - path to JSON formatted file to merge)" "\n"
R"(@param anchor-path - JSON path to anchor merge operation. Defaults to "")" "\n",
ConsoleFunctorFlags::Null, AZ::TypeId::CreateNull(), registry, &ConsoleMergeFileToSettingsRegistry);
return resultHandle;
}
@@ -14,15 +14,16 @@
namespace AZ::SettingsRegistryConsoleUtils
{
//! Only 4 console command are registered for the settings registry
//! "regset", "regremove", "regdump", "regdumpall"
//! The following console command are registered for the settings registry
//! "regset", "regremove", "regdump", "regdumpall", "regset-file"
//! The value should be increased if more commands are needed
inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 4;
inline constexpr size_t MaxSettingsRegistryConsoleFunctors = 5;
inline constexpr const char* SettingsRegistrySet = "sr_regset";
inline constexpr const char* SettingsRegistryRemove = "sr_regremove";
inline constexpr const char* SettingsRegistryDump = "sr_regdump";
inline constexpr const char* SettingsRegistryDumpAll = "sr_regdumpall";
inline constexpr const char* SettingsRegistryMergeFile = "sr_regset-file";
// RAII structure which owns the instances of the Settings Registry Console commands
// registered with an AZ Console
@@ -51,6 +52,10 @@ namespace AZ::SettingsRegistryConsoleUtils
//!
//! "sr_regdumpall" accepts 0 arguments and dumps the entire settings registry
//! NOTE: this might result in a large amount of output to the console
//!
//! "sr_regset-file" accepts 1 or 2 arguments - <file-path> [<anchor json path>]
//! Merges the json formatted file <file path> into the settings registry underneath the root anchor ""
//! or <anchor json path> if supplied
[[nodiscard]] ConsoleFunctorHandle RegisterAzConsoleCommands(SettingsRegistryInterface& registry, AZ::IConsole& azConsole);
}
@@ -19,9 +19,6 @@
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Settings/CommandLine.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/tuple.h>
#include <AzCore/std/containers/variant.h>
#include <AzCore/Utils/Utils.h>
#include <cinttypes>
@@ -983,7 +980,7 @@ namespace AZ::SettingsRegistryMergeUtils
// code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy
// ensures that the iterators remain valid.
// NOLINTNEXTLINE(performance-unnecessary-value-param)
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands)
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeRegdumpCommands)
{
// Iterate over all the command line options in order to parse the --regset and --regremove
// arguments in the order they were supplied
@@ -998,18 +995,44 @@ namespace AZ::SettingsRegistryMergeUtils
continue;
}
}
else if (commandArgument.m_option == "regset-file")
{
AZStd::string_view fileArg(commandArgument.m_value);
AZStd::string_view jsonAnchorPath;
// double colons is treated as the separator for an anchor path
// single colon cannot be used as it is used in Windows paths
if (auto anchorPathIndex = AZ::StringFunc::Find(fileArg, "::");
anchorPathIndex != AZStd::string_view::npos)
{
jsonAnchorPath = fileArg.substr(anchorPathIndex + 2);
fileArg = fileArg.substr(0, anchorPathIndex);
}
if (!fileArg.empty())
{
AZ::IO::PathView filePath(fileArg);
const auto mergeFormat = filePath.Extension() != ".setregpatch"
? AZ::SettingsRegistryInterface::Format::JsonMergePatch
: AZ::SettingsRegistryInterface::Format::JsonPatch;
if (!registry.MergeSettingsFile(filePath.Native(), mergeFormat, jsonAnchorPath))
{
AZ_Warning("SettingsRegistryMergeUtils", false, R"(Merging of file "%.*s" to the Settings Registry has failed at anchor "%.*s".)",
AZ_STRING_ARG(filePath.Native()), AZ_STRING_ARG(jsonAnchorPath));
continue;
}
}
}
else if (commandArgument.m_option == "regremove")
{
if (!registry.Remove(commandArgument.m_value))
{
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to remove value at JSON Pointer %s for --regremove.",
commandArgument.m_value.data());
commandArgument.m_value.c_str());
continue;
}
}
}
if (executeCommands)
if (executeRegdumpCommands)
{
constexpr bool prettifyOutput = true;
const size_t regdumpSwitchValues = commandLine.GetNumSwitchValues("regdump");
@@ -157,6 +157,22 @@ namespace AZ::Statistics
}
}
void GetAllStatistics(AZStd::vector<NamedRunningStatistic*>& stats)
{
for (auto& iter : m_profilers)
{
iter.second.m_profiler.GetStatsManager().GetAllStatistics(stats);
}
}
void GetAllStatisticsOfUnits(AZStd::vector<NamedRunningStatistic*>& stats, const char* units)
{
for (auto& iter : m_profilers)
{
iter.second.m_profiler.GetStatsManager().GetAllStatisticsOfUnits(stats, units);
}
}
private:
struct ProfilerInfo
{
@@ -56,13 +56,25 @@ namespace AZ
void GetAllStatistics(AZStd::vector<NamedRunningStatistic*>& vector)
{
for (auto const& it : m_statistics)
for (const auto& it : m_statistics)
{
NamedRunningStatistic* stat = it.second;
vector.push_back(stat);
}
}
void GetAllStatisticsOfUnits(AZStd::vector<NamedRunningStatistic*>& vector, const char* units)
{
for (const auto& it : m_statistics)
{
NamedRunningStatistic* stat = it.second;
if (stat->GetUnits() == units)
{
vector.push_back(stat);
}
}
}
//! Helper method to apply units to statistics with empty units string.
AZ::u32 ApplyUnits(const AZStd::string& units)
{
@@ -187,6 +187,8 @@ set(FILES
IO/Path/Path.inl
IO/Path/PathIterable.inl
IO/Path/PathParser.inl
IO/Path/PathReflect.cpp
IO/Path/PathReflect.h
IO/Path/Path_fwd.h
IO/SystemFile.cpp
IO/SystemFile.h
@@ -1233,6 +1233,14 @@ namespace AZStd
right.swap(AZStd::forward<this_type>(left));
}
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class U>
decltype(auto) erase(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, const U& value)
{
auto iter = AZStd::remove(container.begin(), container.end(), value);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class T, class Allocator, AZStd::size_t NumElementsPerBlock, AZStd::size_t MinMapSize, class Predicate>
decltype(auto) erase_if(deque<T, Allocator, NumElementsPerBlock, MinMapSize>& container, Predicate predicate)
{
@@ -974,4 +974,22 @@ namespace AZStd
{
return !operator<(a, b);
}
// C++20 erase free functions
template<class T, size_t Capacity, class U>
constexpr decltype(auto) erase(fixed_vector<T, Capacity>& container, const U& value)
{
auto iter = AZStd::remove(container.begin(), container.end(), value);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class T, size_t Capacity, class Predicate>
constexpr decltype(auto) erase_if(fixed_vector<T, Capacity>& container, Predicate predicate)
{
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
}
@@ -1275,6 +1275,11 @@ namespace AZStd
return !(left == right);
}
template<class T, class Allocator, class U>
decltype(auto) erase(forward_list<T, Allocator>& container, const U& value)
{
return container.remove(value);
}
template<class T, class Allocator, class Predicate>
decltype(auto) erase_if(forward_list<T, Allocator>& container, Predicate predicate)
{
@@ -1340,6 +1340,11 @@ namespace AZStd
return !(left == right);
}
template<class T, class Allocator, class U>
decltype(auto) erase(list<T, Allocator>& container, const U& value)
{
return container.remove(value);
}
template<class T, class Allocator, class Predicate>
decltype(auto) erase_if(list<T, Allocator>& container, Predicate predicate)
{
@@ -1387,6 +1387,14 @@ namespace AZStd
}
//#pragma endregion
template<class T, class Allocator, class U>
decltype(auto) erase(vector<T, Allocator>& container, const U& value)
{
auto iter = AZStd::remove(container.begin(), container.end(), value);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class T, class Allocator, class Predicate>
decltype(auto) erase_if(vector<T, Allocator>& container, Predicate predicate)
{
@@ -465,6 +465,15 @@ namespace AZStd
template<class Element, size_t MaxElementCount, class Traits>
constexpr bool operator>=(const Element* lhs, const basic_fixed_string<Element, MaxElementCount, Traits>& rhs);
// C++20 erase helpers
template<class Element, size_t MaxElementCount, class Traits, class U>
constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type;
template<class T>
struct hash;
@@ -11,7 +11,7 @@
#include <stdarg.h>
#include <cstring>
#include <AzCore/std/typetraits/is_integral.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/string/fixed_string_Platform.inl>
@@ -1680,6 +1680,26 @@ namespace AZStd
return !operator<(lhs, rhs);
}
template<class Element, size_t MaxElementCount, class Traits, class U>
inline constexpr auto erase(basic_fixed_string<Element, MaxElementCount, Traits>& container, const U& element)
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
{
auto iter = AZStd::remove(container.begin(), container.end(), element);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class Element, size_t MaxElementCount, class Traits, class Predicate>
inline constexpr auto erase_if(basic_fixed_string<Element, MaxElementCount, Traits>& container, Predicate predicate)
-> typename basic_fixed_string<Element, MaxElementCount, Traits>::size_type
{
auto iter = AZStd::remove_if(container.begin(), container.end(), predicate);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class Element, size_t MaxElementCount, class Traits>
struct hash<basic_fixed_string<Element, MaxElementCount, Traits>>
{
@@ -1955,6 +1955,16 @@ namespace AZStd
{
return basic_string<Element, Traits, Allocator>(lhs).compare(rhs) >= 0;
}
template<class Element, class Traits, class Allocator, class U>
decltype(auto) erase(basic_string<Element, Traits, Allocator>& container, const U& element)
{
auto iter = AZStd::remove(container.begin(), container.end(), element);
auto removedCount = AZStd::distance(iter, container.end());
container.erase(iter, container.end());
return removedCount;
}
template<class Element, class Traits, class Allocator, class Predicate>
decltype(auto) erase_if(basic_string<Element, Traits, Allocator>& container, Predicate predicate)
{
@@ -53,10 +53,8 @@
// Compiler traits ...
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 0
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 1
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 1
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 0
@@ -53,10 +53,8 @@
// Compiler traits ...
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 1
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
@@ -53,10 +53,8 @@
// Compiler traits ...
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
@@ -53,10 +53,8 @@
// Compiler traits ...
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 0
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 0
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 0
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 0
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 0
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 0
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
@@ -53,10 +53,8 @@
// Compiler traits ...
#define AZ_TRAIT_COMPILER_DEFINE_AZSWNPRINTF_AS_SWPRINTF 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_ERRNO_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_FS_STAT_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_GETCURRENTPROCESSID 1
#define AZ_TRAIT_COMPILER_DEFINE_REFGUID 1
#define AZ_TRAIT_COMPILER_DEFINE_SASSERTDATA_TYPE 1
#define AZ_TRAIT_COMPILER_DEFINE_WCSICMP 0
#define AZ_TRAIT_COMPILER_INT64_T_IS_LONG 0
#define AZ_TRAIT_COMPILER_OPTIMIZE_MISSING_DEFAULT_SWITCH_CASE 1
+41 -6
View File
@@ -2376,17 +2376,52 @@ namespace UnitTest
static_assert(AZStd::wildcard_match_case(filter1, blahValue));
}
TEST_F(String, StringEraseIf_Succeeds)
TEST_F(String, StringCXX20Erase_Succeeds)
{
AZStd::string eraseIfTest = "ABC CBA";
auto eraseCount = AZStd::erase_if(eraseIfTest, [](AZStd::string::value_type ch)
{
return ch == 'C';
});
auto erasePredicate = [](AZStd::string::value_type ch)
{
return ch == 'C';
};
auto eraseCount = AZStd::erase_if(eraseIfTest, erasePredicate);
EXPECT_EQ(2, eraseCount);
EXPECT_EQ(5, eraseIfTest.size());
EXPECT_STREQ("AB BA", eraseIfTest.c_str());
// Now erase the letter 'A';
eraseCount = AZStd::erase(eraseIfTest, 'A');
EXPECT_EQ(2, eraseCount);
EXPECT_EQ(3, eraseIfTest.size());
EXPECT_EQ("B B", eraseIfTest);
}
TEST_F(String, FixedStringCXX20Erase_Succeeds)
{
// Erase 'l' from the phrase "Hello" World"
constexpr auto eraseTest = [](const char* testString) constexpr
{
AZStd::fixed_string<16> testResult{ testString };
AZStd::erase(testResult, 'l');
return testResult;
}("HelloWorld");
static_assert(eraseTest == "HeoWord");
EXPECT_EQ("HeoWord", eraseTest);
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
constexpr auto eraseIfTest = [](AZStd::string_view testString) constexpr
{
AZStd::fixed_string<16> testResult{ testString };
auto erasePredicate = [](char ch)
{
return ch == 'H' || ch == 'e';
};
AZStd::erase_if(testResult, erasePredicate);
return testResult;
}(eraseTest);
static_assert(eraseIfTest == "oWord");
EXPECT_EQ("oWord", eraseIfTest);
}
template <typename StringType>
@@ -796,6 +796,37 @@ namespace UnitTest
EXPECT_GT(greaterVectorDifferentSize, lessVector);
}
TEST_F(Arrays, FixedVectorCXX20Erase_Succeeds)
{
// Erase 'l' from the phrase "Hello" World"
auto eraseTest = [](AZStd::initializer_list<char> testInit)
{
AZStd::fixed_vector<char, 16> testResult{ testInit };
AZStd::erase(testResult, 'l');
return testResult;
}({ 'H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd' });
constexpr AZStd::string_view expectedEraseString = "HeoWord";
AZStd::string_view testEraseString{ eraseTest.begin(), eraseTest.end() };
EXPECT_EQ(expectedEraseString, testEraseString);
// Use erase_if to erase both 'H' and 'e' from the remaining eraseTest string
auto eraseIfTest = [](const AZStd::fixed_vector<char, 16>& testVector)
{
AZStd::fixed_vector<char, 16> testResult{ testVector };
auto erasePredicate = [](char ch)
{
return ch == 'H' || ch == 'e';
};
AZStd::erase_if(testResult, erasePredicate);
return testResult;
}(testEraseString);
constexpr AZStd::string_view expectedEraseIfString = "oWord";
AZStd::string_view testEraseIfString{ eraseIfTest.begin(), eraseIfTest.end() };
EXPECT_EQ(expectedEraseIfString, testEraseIfString);
}
TEST_F(Arrays, VectorSwap)
{
vector<void*> vec1(42, nullptr);
@@ -33,6 +33,15 @@ namespace MathTestData
AZ::Matrix3x3::CreateScale(AZ::Vector3(0.7f, 1.3f, 0.9f))
};
static const AZ::Matrix4x4 Matrix4x4s[] = {
AZ::Matrix4x4::CreateIdentity(),
AZ::Matrix4x4::CreateFromQuaternionAndTranslation(AZ::Quaternion(-0.46f, 0.26f, -0.22f, 0.82f), AZ::Vector3(1.0f, 5.0f, 10.0f)),
AZ::Matrix4x4::CreateFromTransform(AZ::Transform::CreateFromMatrix3x3AndTranslation(
AZ::Matrix3x3::CreateScale(AZ::Vector3(1.0f, 2.0f, 3.0f)), AZ::Vector3(2.0f, 4.0f, 6.0f))),
AZ::Matrix4x4::CreateScale(AZ::Vector3(5.0f, 10.0f, 15.0f)),
AZ::Matrix4x4::CreateRotationZ(AZ::DegToRad(45.0f))
};
using AxisPair = AZStd::pair<AZ::Constants::Axis, AZ::Vector3>;
static const AxisPair Axes[] = {
{ AZ::Constants::Axis::XPositive, AZ::Vector3::CreateAxisX(1.0f) },
@@ -10,6 +10,7 @@
#include <AzCore/Math/Matrix3x4.h>
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Quaternion.h>
#include <AzCore/Math/VectorConversions.h>
#include <AZTestShared/Math/MathTestHelpers.h>
#include "MathTestData.h"
@@ -392,6 +393,32 @@ namespace UnitTest
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4CreateFromMatrix3x3Fixture, ::testing::ValuesIn(MathTestData::Matrix3x3s));
using Matrix3x4CreateFromMatrix4x4Fixture = ::testing::TestWithParam<AZ::Matrix4x4>;
TEST_P(Matrix3x4CreateFromMatrix4x4Fixture, UnsafeCreateFromMatrix4x4)
{
const AZ::Matrix4x4 matrix4x4 = GetParam();
const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::UnsafeCreateFromMatrix4x4(matrix4x4);
EXPECT_THAT(matrix3x4.GetTranslation(), IsClose(matrix4x4.GetTranslation()));
const AZ::Vector3 vector(2.3f, -0.6, 1.8f);
EXPECT_THAT(matrix3x4.TransformVector(vector), IsClose((matrix4x4 * AZ::Vector3ToVector4(vector, 0.0f)).GetAsVector3()));
const AZ::Vector3 point(12.3f, -5.6, 7.3f);
EXPECT_THAT(matrix3x4.TransformPoint(point), IsClose((matrix4x4 * AZ::Vector3ToVector4(point, 1.0f)).GetAsVector3()));
}
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4CreateFromMatrix4x4Fixture, ::testing::ValuesIn(MathTestData::Matrix4x4s));
TEST(MATH_Matrix3x4, TransformPoint)
{
const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromMatrix3x3AndTranslation(
AZ::Matrix3x3::CreateRotationY(AZ::DegToRad(90.0f)), AZ::Vector3(5.0f, 0.0f, 0.0f));
const AZ::Vector3 result = matrix3x4.TransformPoint(AZ::Vector3(1.0f, 0.0f, 0.0f));
const AZ::Vector3 expected = AZ::Vector3(5.0f, 0.0f, -1.0f);
EXPECT_THAT(result, expected);
}
TEST(MATH_Matrix3x4, CreateScale)
{
const AZ::Vector3 scale(1.7f, 0.3f, 2.4f);
@@ -59,6 +59,7 @@
#include <AzCore/IO/SystemFile.h>
#include <AzCore/IO/ByteContainerStream.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/Path/PathReflect.h>
#include <AzCore/IO/Streamer/StreamerComponent.h>
#include <AzCore/RTTI/AttributeReader.h>
@@ -8151,5 +8152,98 @@ namespace UnitTest
m_serializeContext->Class<TestClassWithEnumFieldThatSpecializesTypeInfo>();
m_serializeContext->DisableRemoveReflection();
}
template <typename ParamType>
class PathSerializationParamFixture
: public ScopedAllocatorSetupFixture
, public ::testing::WithParamInterface<ParamType>
{
public:
PathSerializationParamFixture()
: ScopedAllocatorSetupFixture(
[]() { AZ::SystemAllocator::Descriptor desc; desc.m_stackRecordLevels = 30; return desc; }()
)
{}
// We must expose the class for serialization first.
void SetUp() override
{
m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
AZ::IO::PathReflect(m_serializeContext.get());
}
void TearDown() override
{
m_serializeContext->EnableRemoveReflection();
AZ::IO::PathReflect(m_serializeContext.get());
m_serializeContext->DisableRemoveReflection();
m_serializeContext.reset();
}
protected:
AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
};
struct PathSerializationParams
{
const char m_preferredSeparator{};
const char* m_testPath{};
};
using PathSerializationFixture = PathSerializationParamFixture<PathSerializationParams>;
TEST_P(PathSerializationFixture, PathSerializer_SerializesStringBackedPath_Succeeds)
{
const auto& testParams = GetParam();
{
// Path serialization
AZ::IO::Path testPath{ testParams.m_testPath, testParams.m_preferredSeparator };
AZStd::vector<char> byteBuffer;
AZ::IO::ByteContainerStream byteStream(&byteBuffer);
auto objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, AZ::ObjectStream::ST_XML);
objStream->WriteClass(&testPath);
objStream->Finalize();
byteStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
AZ::IO::Path loadPath{ testParams.m_preferredSeparator };
EXPECT_TRUE(AZ::Utils::LoadObjectFromStreamInPlace(byteStream, loadPath, m_serializeContext.get()));
EXPECT_EQ(testPath.LexicallyNormal(), loadPath);
}
{
// FixedMaxPath serialization
AZ::IO::FixedMaxPath testFixedMaxPath{ testParams.m_testPath, testParams.m_preferredSeparator };
AZStd::vector<char> byteBuffer;
AZ::IO::ByteContainerStream byteStream(&byteBuffer);
auto objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, AZ::ObjectStream::ST_XML);
objStream->WriteClass(&testFixedMaxPath);
objStream->Finalize();
byteStream.Seek(0, AZ::IO::GenericStream::ST_SEEK_BEGIN);
AZ::IO::FixedMaxPath loadPath{ testParams.m_preferredSeparator };
EXPECT_TRUE(AZ::Utils::LoadObjectFromStreamInPlace(byteStream, loadPath, m_serializeContext.get()));
EXPECT_EQ(testFixedMaxPath.LexicallyNormal(), loadPath);
}
}
INSTANTIATE_TEST_CASE_P(
PathSerialization,
PathSerializationFixture,
::testing::Values(
PathSerializationParams{ AZ::IO::PosixPathSeparator, "" },
PathSerializationParams{ AZ::IO::PosixPathSeparator, "test" },
PathSerializationParams{ AZ::IO::PosixPathSeparator, "/test" },
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "test" },
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "/test" },
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "D:test" },
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "D:/test" },
PathSerializationParams{ AZ::IO::WindowsPathSeparator, "test/foo/../bar" }
)
);
}
@@ -539,6 +539,22 @@ tags=tools,renderer,metal)"
EXPECT_STREQ("Bat", commandLine.GetMiscValue(2).c_str());
}
TEST_F(SettingsRegistryMergeUtilsCommandLineFixture, RegsetFileArgument_DoesNotMergeNUL)
{
AZStd::string regsetFile = AZ::IO::SystemFile::GetNullFilename();
AZ::CommandLine commandLine;
commandLine.Parse({ "--regset-file", regsetFile });
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false);
// Add a settings path to anchor loaded settings underneath
regsetFile = AZStd::string::format("%s::/AnchorPath/Of/Settings", AZ::IO::SystemFile::GetNullFilename());
commandLine.Parse({ "--regset-file", regsetFile });
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_registry, commandLine, false);
EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/AnchorPath/Of/Settings"));
}
using SettingsRegistryAncestorDescendantOrEqualPathFixture = SettingsRegistryMergeUtilsCommandLineFixture;
TEST_F(SettingsRegistryAncestorDescendantOrEqualPathFixture, ValidateThatAncestorOrDescendantOrPathWithTheSameValue_Succeeds)
@@ -46,11 +46,6 @@ namespace AZ::IO
"If set to 0, tells Archive to try to open the file on the file system first othewise check mounted paks.\n"
"If set to 1, tells Archive to try to open the file in pak first, then go to file system.\n"
"If set to 2, tells the Archive to only open files from the pak");
AZ_CVAR(int, sys_PakMessageInvalidFileAccess, ArchiveVars{}.nMessageInvalidFileAccess, nullptr, AZ::ConsoleFunctorFlags::Null,
"Message Box synchronous file access when in game");
AZ_CVAR(int, sys_PakWarnOnPakAccessFailures, ArchiveVars{}.nWarnOnPakAccessFails, nullptr, AZ::ConsoleFunctorFlags::Null,
"If 1, access failure for Paks is treated as a warning, if zero it is only a log message.");
AZ_CVAR(int, sys_report_files_not_found_in_paks, 0, nullptr, AZ::ConsoleFunctorFlags::Null,
"Reports when files are searched for in paks and not found. 1 = log, 2 = warning, 3 = error");
AZ_CVAR(int32_t, az_archive_verbosity, 0, nullptr, AZ::ConsoleFunctorFlags::Null,
@@ -9,8 +9,6 @@
#pragma once
#include <AzFramework/Archive/ArchiveVars_Platform.h>
namespace AZ::IO
{
enum class FileSearchPriority
@@ -39,25 +37,10 @@ namespace AZ::IO
#else
inline static constexpr bool IsReleaseConfig{};
#endif
int nReadSlice{};
int nSaveTotalResourceList{};
int nSaveFastloadResourceList{};
int nSaveMenuCommonResourceList{};
int nSaveLevelResourceList{};
int nValidateFileHashes{ IsReleaseConfig ? 0 : 1 };
int nUncachedStreamReads{ 1 };
int nInMemoryPerPakSizeLimit{ 6 }; // Limits in MB
int nTotalInMemoryPakSizeLimit{ 30 };
int nLoadCache{};
int nLoadModePaks{};
int nStreamCache{ STREAM_CACHE_DEFAULT };
FileSearchPriority m_fileSearchPriority{ GetDefaultFileSearchPriority()};
int nMessageInvalidFileAccess{};
int nLogInvalidFileAccess{ IsReleaseConfig ? 0 : 1 };
int nDisableNonLevelRelatedPaks{ 1 };
int nWarnOnPakAccessFails{ 1 }; // Whether to treat failed pak access as a warning or log message
int nSetLogLevel{ 3 };
int nLogAllFileAccess{};
};
}
@@ -26,10 +26,11 @@ namespace AzFramework::Terrain
->Event("GetSurfaceWeights", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeights)
->Event("GetSurfaceWeightsFromVector2",
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfaceWeightsFromVector2)
->Event("GetIsHole", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHole)
->Event("GetIsHoleFromFloats", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetIsHoleFromFloats)
->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePoint)
->Event("GetSurfacePoint", &AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePoint)
->Event("GetSurfacePointFromVector2",
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetSurfacePointFromVector2)
&AzFramework::Terrain::TerrainDataRequestBus::Events::BehaviorContextGetSurfacePointFromVector2)
->Event("GetTerrainAabb", &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb)
->Event("GetTerrainHeightQueryResolution",
&AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainHeightQueryResolution)
@@ -52,8 +52,8 @@ namespace AzFramework
virtual void SetTerrainAabb(const AZ::Aabb& worldBounds) = 0;
//! Returns terrains height in meters at location x,y.
//! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will become false,
//! otherwise *terrainExistsPtr will become true.
//! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside
//! a terrain HOLE then *terrainExistsPtr will become false, otherwise *terrainExistsPtr will become true.
virtual float GetHeight(const AZ::Vector3& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
virtual float GetHeightFromVector2(
const AZ::Vector2& position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
@@ -68,8 +68,7 @@ namespace AzFramework
// Given an XY coordinate, return the surface normal.
//! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a
//! terrain HOLE then *terrainExistsPtr will be set to false,
//! otherwise *terrainExistsPtr will be set to true.
//! terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true.
virtual AZ::Vector3 GetNormal(
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
virtual AZ::Vector3 GetNormalFromVector2(
@@ -78,8 +77,8 @@ namespace AzFramework
float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
//! Given an XY coordinate, return the max surface type and weight.
//! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain HOLE then *terrainExistsPtr will be set to false,
//! otherwise *terrainExistsPtr will be set to true.
//! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside
//! a terrain HOLE then *terrainExistsPtr will be set to false, otherwise *terrainExistsPtr will be set to true.
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight(
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromVector2(
@@ -87,8 +86,8 @@ namespace AzFramework
virtual SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats(
float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
//! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to ignore
//! the input Z value.
//! Given an XY coordinate, return the set of surface types and weights. The Vector3 input position version is defined to
//! ignore the input Z value.
virtual void GetSurfaceWeights(
const AZ::Vector3& inPosition,
SurfaceData::SurfaceTagWeightList& outSurfaceWeights,
@@ -106,13 +105,14 @@ namespace AzFramework
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const = 0;
//! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats.
//! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use
//! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats.
//! Not available in the behavior context.
//! Returns nullptr if the position is inside a hole or outside of the terrain boundaries.
virtual const char* GetMaxSurfaceName(
const AZ::Vector3& position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const = 0;
//! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined
//! Given an XY coordinate, return all terrain information at that location. The Vector3 input position version is defined
//! to ignore the input Z value.
virtual void GetSurfacePoint(
const AZ::Vector3& inPosition,
@@ -130,6 +130,27 @@ namespace AzFramework
SurfaceData::SurfacePoint& outSurfacePoint,
Sampler sampleFilter = Sampler::DEFAULT,
bool* terrainExistsPtr = nullptr) const = 0;
private:
// Private variations of the GetSurfacePoint API exposed to BehaviorContext that returns a value instead of
// using an "out" parameter. The "out" parameter is useful for reusing memory allocated in SurfacePoint when
// using the public API, but can't easily be used from Script Canvas.
SurfaceData::SurfacePoint BehaviorContextGetSurfacePoint(
const AZ::Vector3& inPosition,
Sampler sampleFilter = Sampler::DEFAULT) const
{
SurfaceData::SurfacePoint result;
GetSurfacePoint(inPosition, result, sampleFilter);
return result;
}
SurfaceData::SurfacePoint BehaviorContextGetSurfacePointFromVector2(
const AZ::Vector2& inPosition,
Sampler sampleFilter = Sampler::DEFAULT) const
{
SurfaceData::SurfacePoint result;
GetSurfacePointFromVector2(inPosition, result, sampleFilter);
return result;
}
};
using TerrainDataRequestBus = AZ::EBus<TerrainDataRequests>;
@@ -15,6 +15,7 @@
namespace AZ
{
class Matrix4x4;
class Matrix3x4;
class Transform;
class ReflectContext;
} // namespace AZ
@@ -32,6 +33,8 @@ namespace AzFramework
//! Gets the current camera's world to view matrix.
virtual const AZ::Matrix4x4& GetCameraViewMatrix() const = 0;
//! Gets the current camera's world to view matrix as a Matrix3x4.
virtual AZ::Matrix3x4 GetCameraViewMatrixAsMatrix3x4() const = 0;
//! Sets the current camera's world to view matrix.
virtual void SetCameraViewMatrix(const AZ::Matrix4x4& matrix) = 0;
//! Gets the current camera's projection (view to clip) matrix.
@@ -31,34 +31,31 @@ namespace AzFramework
// multiplication which must be used (see CameraTransformFromCameraView and CameraViewFromCameraTransform)
// note: coordinate system convention is right handed
// see Matrix4x4::CreateProjection for more details
static AZ::Matrix4x4 ZYCoordinateSystemConversion()
static AZ::Matrix3x4 ZYCoordinateSystemConversion()
{
// note: the below matrix is the result of these combined transformations
// pitch = AZ::Matrix4x4::CreateRotationX(AZ::DegToRad(-90.0f));
// yaw = AZ::Matrix4x4::CreateRotationZ(AZ::DegToRad(180.0f));
// conversion = pitch * yaw
return AZ::Matrix4x4::CreateFromColumns(
AZ::Vector4(-1.0f, 0.0f, 0.0f, 0.0f), AZ::Vector4(0.0f, 0.0f, 1.0f, 0.0f), AZ::Vector4(0.0f, 1.0f, 0.0f, 0.0f),
AZ::Vector4(0.0f, 0.0f, 0.0f, 1.0f));
return AZ::Matrix3x4::CreateFromColumns(
AZ::Vector3(-1.0f, 0.0f, 0.0f), AZ::Vector3(0.0f, 0.0f, 1.0f), AZ::Vector3(0.0f, 1.0f, 0.0f), AZ::Vector3(0.0f, 0.0f, 0.0f));
}
AZ::Matrix4x4 CameraTransform(const CameraState& cameraState)
AZ::Matrix3x4 CameraTransform(const CameraState& cameraState)
{
return AZ::Matrix4x4::CreateFromColumns(
AZ::Vector3ToVector4(cameraState.m_side), AZ::Vector3ToVector4(cameraState.m_forward), AZ::Vector3ToVector4(cameraState.m_up),
AZ::Vector3ToVector4(cameraState.m_position, 1.0f));
return AZ::Matrix3x4::CreateFromColumns(cameraState.m_side, cameraState.m_forward, cameraState.m_up, cameraState.m_position);
}
AZ::Matrix4x4 CameraView(const CameraState& cameraState)
AZ::Matrix3x4 CameraView(const CameraState& cameraState)
{
// ensure the camera is looking down positive z with the x axis pointing left
return ZYCoordinateSystemConversion() * CameraTransform(cameraState).GetInverseTransform();
return ZYCoordinateSystemConversion() * CameraTransform(cameraState).GetInverseFast();
}
AZ::Matrix4x4 InverseCameraView(const CameraState& cameraState)
AZ::Matrix3x4 InverseCameraView(const CameraState& cameraState)
{
// ensure the camera is looking down positive z with the x axis pointing left
return CameraView(cameraState).GetInverseTransform();
return CameraView(cameraState).GetInverseFast();
}
AZ::Matrix4x4 CameraProjection(const CameraState& cameraState)
@@ -72,14 +69,14 @@ namespace AzFramework
return CameraProjection(cameraState).GetInverseFull();
}
AZ::Matrix4x4 CameraTransformFromCameraView(const AZ::Matrix4x4& cameraView)
AZ::Matrix3x4 CameraTransformFromCameraView(const AZ::Matrix3x4& cameraView)
{
return (ZYCoordinateSystemConversion() * cameraView).GetInverseTransform();
return (ZYCoordinateSystemConversion() * cameraView).GetInverseFast();
}
AZ::Matrix4x4 CameraViewFromCameraTransform(const AZ::Matrix4x4& cameraTransform)
AZ::Matrix3x4 CameraViewFromCameraTransform(const AZ::Matrix3x4& cameraTransform)
{
return ZYCoordinateSystemConversion() * cameraTransform.GetInverseTransform();
return ZYCoordinateSystemConversion() * cameraTransform.GetInverseFast();
}
AZ::Frustum FrustumFromCameraState(const CameraState& cameraState)
@@ -91,16 +88,17 @@ namespace AzFramework
{
const auto worldFromView = AzFramework::CameraTransform(cameraState);
const auto cameraWorldTransform = AZ::Transform::CreateFromMatrix3x3AndTranslation(
AZ::Matrix3x3::CreateFromMatrix4x4(worldFromView), worldFromView.GetTranslation());
AZ::Matrix3x3::CreateFromMatrix3x4(worldFromView), worldFromView.GetTranslation());
return AZ::ViewFrustumAttributes(
cameraWorldTransform, AspectRatio(cameraState.m_viewportSize), cameraState.m_fovOrZoom, cameraState.m_nearClip,
cameraState.m_farClip);
}
AZ::Vector3 WorldToScreenNdc(const AZ::Vector3& worldPosition, const AZ::Matrix4x4& cameraView, const AZ::Matrix4x4& cameraProjection)
AZ::Vector3 WorldToScreenNdc(const AZ::Vector3& worldPosition, const AZ::Matrix3x4& cameraView, const AZ::Matrix4x4& cameraProjection)
{
// transform the world space position to clip space
const auto clipSpacePosition = cameraProjection * cameraView * AZ::Vector3ToVector4(worldPosition, 1.0f);
const auto clipSpacePosition =
cameraProjection * AZ::Vector3ToVector4(cameraView.TransformPoint(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
@@ -109,7 +107,7 @@ namespace AzFramework
ScreenPoint WorldToScreen(
const AZ::Vector3& worldPosition,
const AZ::Matrix4x4& cameraView,
const AZ::Matrix3x4& cameraView,
const AZ::Matrix4x4& cameraProjection,
const AZ::Vector2& viewportSize)
{
@@ -123,7 +121,7 @@ namespace AzFramework
}
AZ::Vector3 ScreenNdcToWorld(
const AZ::Vector2& normalizedScreenPosition, const AZ::Matrix4x4& inverseCameraView, const AZ::Matrix4x4& inverseCameraProjection)
const AZ::Vector2& normalizedScreenPosition, const AZ::Matrix3x4& inverseCameraView, const AZ::Matrix4x4& inverseCameraProjection)
{
// convert screen space coordinates from <0, 1> to <-1,1> range
const auto ndcPosition = normalizedScreenPosition * 2.0f - AZ::Vector2::CreateOne();
@@ -140,7 +138,7 @@ namespace AzFramework
AZ::Vector3 ScreenToWorld(
const ScreenPoint& screenPosition,
const AZ::Matrix4x4& inverseCameraView,
const AZ::Matrix3x4& inverseCameraView,
const AZ::Matrix4x4& inverseCameraProjection,
const AZ::Vector2& viewportSize)
{
@@ -16,6 +16,7 @@
namespace AZ
{
class Frustum;
class Matrix3x4;
class Matrix4x4;
struct ViewFrustumAttributes;
} // namespace AZ
@@ -43,7 +44,7 @@ namespace AzFramework
}
//! 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);
AZ::Vector3 WorldToScreenNdc(const AZ::Vector3& worldPosition, const AZ::Matrix3x4& 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);
@@ -52,7 +53,7 @@ namespace AzFramework
//! is called many times in a loop.
ScreenPoint WorldToScreen(
const AZ::Vector3& worldPosition,
const AZ::Matrix4x4& cameraView,
const AZ::Matrix3x4& cameraView,
const AZ::Matrix4x4& cameraProjection,
const AZ::Vector2& viewportSize);
@@ -64,14 +65,14 @@ namespace AzFramework
//! is called many times in a loop.
AZ::Vector3 ScreenToWorld(
const ScreenPoint& screenPosition,
const AZ::Matrix4x4& inverseCameraView,
const AZ::Matrix3x4& inverseCameraView,
const AZ::Matrix4x4& inverseCameraProjection,
const AZ::Vector2& viewportSize);
//! Unprojects a position in screen space normalized device coordinates to world space.
//! Note: The position returned will be on the near clip plane of the camera in world space.
AZ::Vector3 ScreenNdcToWorld(
const AZ::Vector2& ndcPosition, const AZ::Matrix4x4& inverseCameraView, const AZ::Matrix4x4& inverseCameraProjection);
const AZ::Vector2& ndcPosition, const AZ::Matrix3x4& inverseCameraView, const AZ::Matrix4x4& inverseCameraProjection);
//! Returns the camera projection for the current camera state.
AZ::Matrix4x4 CameraProjection(const CameraState& cameraState);
@@ -81,27 +82,27 @@ namespace AzFramework
//! Returns the camera view for the current camera state.
//! @note This is the 'v' in the MVP transform going from world space to view space (viewFromWorld).
AZ::Matrix4x4 CameraView(const CameraState& cameraState);
AZ::Matrix3x4 CameraView(const CameraState& cameraState);
//! Returns the inverse of the camera view for the current camera state.
//! @note This is the same as the CameraTransform but corrected for Z up.
AZ::Matrix4x4 InverseCameraView(const CameraState& cameraState);
AZ::Matrix3x4 InverseCameraView(const CameraState& cameraState);
//! Returns the camera transform for the current camera state.
//! @note This is the inverse of 'v' in the MVP transform going from view space to world space (worldFromView).
AZ::Matrix4x4 CameraTransform(const CameraState& cameraState);
AZ::Matrix3x4 CameraTransform(const CameraState& cameraState);
//! Takes a camera view (the world to camera space transform) and returns the
//! corresponding camera transform (the world position and orientation of the camera).
//! @note The parameter is the viewFromWorld transform (the 'v' in MVP) going from world space
//! to view space. The return value is worldFromView transform going from view space to world space.
AZ::Matrix4x4 CameraTransformFromCameraView(const AZ::Matrix4x4& cameraView);
AZ::Matrix3x4 CameraTransformFromCameraView(const AZ::Matrix3x4& cameraView);
//! Takes a camera transform (the world position and orientation of the camera) and
//! returns the corresponding camera view (to be used to transform from world to camera space).
//! @note The parameter is the worldFromView transform going from view space to world space. The
//! return value is viewFromWorld transform (the 'v' in MVP) going from view space to world space.
AZ::Matrix4x4 CameraViewFromCameraTransform(const AZ::Matrix4x4& cameraTransform);
AZ::Matrix3x4 CameraViewFromCameraTransform(const AZ::Matrix3x4& cameraTransform);
//! Returns a frustum representing the camera transform and view volume in world space.
AZ::Frustum FrustumFromCameraState(const CameraState& cameraState);
@@ -143,6 +143,13 @@ namespace AzFramework
return vsync_interval;
}
bool NativeWindow::SetSyncInterval(uint32_t newSyncInterval)
{
vsync_interval = newSyncInterval;
return true;
}
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{
NativeWindowHandle defaultWindowHandle = nullptr;
@@ -132,6 +132,7 @@ namespace AzFramework
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
uint32_t GetSyncInterval() const override;
bool SetSyncInterval(uint32_t newSyncInterval) override;
uint32_t GetDisplayRefreshRate() const override;
//! Get the full screen state of the default window.
@@ -78,6 +78,10 @@ namespace AzFramework
//! Returns the sync interval which tells the drivers the number of v-blanks to synchronize with
virtual uint32_t GetSyncInterval() const = 0;
//! Sets the sync interval which tells the drivers the number of v-blanks to synchronize with
//! Returns if the sync interval was succesfully set
virtual bool SetSyncInterval(uint32_t newSyncInterval) = 0;
//! Returns the refresh rate of the main display
virtual uint32_t GetDisplayRefreshRate() const = 0;
};
@@ -52,6 +52,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
FILES_CMAKE
Tests/framework_shared_tests_files.cmake
AzFramework/Physics/physics_mock_files.cmake
Tests/terrain_mock_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
Tests
@@ -1,10 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Archive/ArchiveVars_Android.h>
@@ -27,8 +27,6 @@ set(FILES
AzFramework/Input/User/LocalUserId_Platform.h
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Android.cpp
AzFramework/Archive/ArchiveVars_Platform.h
AzFramework/Archive/ArchiveVars_Android.h
AzFramework/Process/ProcessCommon.h
AzFramework/Process/ProcessWatcher_Android.cpp
AzFramework/Process/ProcessCommunicator_Android.cpp
@@ -1,11 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#define STREAM_CACHE_DEFAULT 0
@@ -1,10 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Archive/ArchiveVars_Linux.h>
@@ -28,6 +28,4 @@ set(FILES
AzFramework/Input/User/LocalUserId_Platform.h
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
../Common/Unimplemented/AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Unimplemented.cpp
AzFramework/Archive/ArchiveVars_Platform.h
AzFramework/Archive/ArchiveVars_Linux.h
)
@@ -1,11 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#define STREAM_CACHE_DEFAULT 0
@@ -1,10 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Archive/ArchiveVars_Mac.h>
@@ -30,8 +30,6 @@ set(FILES
AzFramework/Input/User/LocalUserId_Platform.h
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
../Common/Unimplemented/AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Unimplemented.cpp
AzFramework/Archive/ArchiveVars_Platform.h
AzFramework/Archive/ArchiveVars_Mac.h
../Common/Apple/AzFramework/Utils/SystemUtilsApple.h
../Common/Apple/AzFramework/Utils/SystemUtilsApple.mm
)
@@ -1,10 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Archive/ArchiveVars_Windows.h>
@@ -1,11 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#define STREAM_CACHE_DEFAULT 0
@@ -32,6 +32,4 @@ set(FILES
AzFramework/Input/User/LocalUserId_Platform.h
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
../Common/Unimplemented/AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Unimplemented.cpp
AzFramework/Archive/ArchiveVars_Platform.h
AzFramework/Archive/ArchiveVars_Windows.h
)
@@ -1,10 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzFramework/Archive/ArchiveVars_iOS.h>
@@ -1,11 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#define STREAM_CACHE_DEFAULT 0
@@ -27,8 +27,6 @@ set(FILES
AzFramework/Input/User/LocalUserId_Platform.h
../Common/Default/AzFramework/Input/User/LocalUserId_Default.h
../Common/Apple/AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard_Apple.mm
AzFramework/Archive/ArchiveVars_Platform.h
AzFramework/Archive/ArchiveVars_iOS.h
AzFramework/Process/ProcessCommon.h
AzFramework/Process/ProcessWatcher_iOS.cpp
AzFramework/Process/ProcessCommunicator_iOS.cpp
@@ -36,6 +36,7 @@ namespace UnitTest
MOCK_METHOD0(ToggleFullScreenState, void());
MOCK_CONST_METHOD0(GetDpiScaleFactor, float());
MOCK_CONST_METHOD0(GetSyncInterval, uint32_t());
MOCK_METHOD1(SetSyncInterval, bool(uint32_t));
MOCK_CONST_METHOD0(GetDisplayRefreshRate, uint32_t());
};
} // namespace UnitTest
@@ -0,0 +1,80 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <gmock/gmock.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzFramework/Physics/HeightfieldProviderBus.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
#include <TerrainSystem/TerrainSystemBus.h>
namespace UnitTest
{
class MockTerrainDataNotificationListener : public AzFramework::Terrain::TerrainDataNotificationBus::Handler
{
public:
MockTerrainDataNotificationListener()
{
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect();
}
~MockTerrainDataNotificationListener()
{
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect();
}
MOCK_METHOD0(OnTerrainDataCreateBegin, void());
MOCK_METHOD0(OnTerrainDataCreateEnd, void());
MOCK_METHOD0(OnTerrainDataDestroyBegin, void());
MOCK_METHOD0(OnTerrainDataDestroyEnd, void());
MOCK_METHOD2(OnTerrainDataChanged, void(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask));
};
class MockTerrainDataRequests : public AzFramework::Terrain::TerrainDataRequestBus::Handler
{
public:
MockTerrainDataRequests()
{
AzFramework::Terrain::TerrainDataRequestBus::Handler::BusConnect();
}
~MockTerrainDataRequests()
{
AzFramework::Terrain::TerrainDataRequestBus::Handler::BusDisconnect();
}
MOCK_CONST_METHOD0(GetTerrainHeightQueryResolution, AZ::Vector2());
MOCK_METHOD1(SetTerrainHeightQueryResolution, void(AZ::Vector2));
MOCK_CONST_METHOD0(GetTerrainAabb, AZ::Aabb());
MOCK_METHOD1(SetTerrainAabb, void(const AZ::Aabb&));
MOCK_CONST_METHOD3(GetHeight, float(const AZ::Vector3&, Sampler, bool*));
MOCK_CONST_METHOD3(GetHeightFromVector2, float(const AZ::Vector2&, Sampler, bool*));
MOCK_CONST_METHOD4(GetHeightFromFloats, float(float, float, Sampler, bool*));
MOCK_CONST_METHOD2(GetIsHole, bool(const AZ::Vector3&, Sampler));
MOCK_CONST_METHOD2(GetIsHoleFromVector2, bool(const AZ::Vector2&, Sampler));
MOCK_CONST_METHOD3(GetIsHoleFromFloats, bool(float, float, Sampler));
MOCK_CONST_METHOD3(GetNormal, AZ::Vector3(const AZ::Vector3&, Sampler, bool*));
MOCK_CONST_METHOD3(GetNormalFromVector2, AZ::Vector3(const AZ::Vector2&, Sampler, bool*));
MOCK_CONST_METHOD4(GetNormalFromFloats, AZ::Vector3(float, float, Sampler, bool*));
MOCK_CONST_METHOD3(GetMaxSurfaceWeight, AzFramework::SurfaceData::SurfaceTagWeight(const AZ::Vector3&, Sampler, bool*));
MOCK_CONST_METHOD3(GetMaxSurfaceWeightFromVector2, AzFramework::SurfaceData::SurfaceTagWeight(const AZ::Vector2&, Sampler, bool*));
MOCK_CONST_METHOD4(GetMaxSurfaceWeightFromFloats, AzFramework::SurfaceData::SurfaceTagWeight(float, float, Sampler, bool*));
MOCK_CONST_METHOD4(GetSurfaceWeights, void(const AZ::Vector3&, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
MOCK_CONST_METHOD4(
GetSurfaceWeightsFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
MOCK_CONST_METHOD5(
GetSurfaceWeightsFromFloats, void(float, float, AzFramework::SurfaceData::SurfaceTagWeightList&, Sampler, bool*));
MOCK_CONST_METHOD3(GetMaxSurfaceName, const char*(const AZ::Vector3&, Sampler, bool*));
MOCK_CONST_METHOD4(GetSurfacePoint, void(const AZ::Vector3&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
MOCK_CONST_METHOD4(
GetSurfacePointFromVector2, void(const AZ::Vector2&, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
MOCK_CONST_METHOD5(
GetSurfacePointFromFloats, void(float, float, AzFramework::SurfaceData::SurfacePoint&, Sampler, bool*));
};
} // namespace UnitTest
@@ -0,0 +1,11 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
set(FILES
Mocks/Terrain/MockTerrainDataRequestBus.h
)
@@ -39,6 +39,10 @@ namespace AzManipulatorTestFramework
DerivedDispatcherT* MouseLButtonDown();
//! Set the left mouse button up.
DerivedDispatcherT* MouseLButtonUp();
//! Set the middle mouse button down.
DerivedDispatcherT* MouseMButtonDown();
//! Set the middle mouse button up.
DerivedDispatcherT* MouseMButtonUp();
//! Send a double click event.
DerivedDispatcherT* MouseLButtonDoubleClick();
//! Set the keyboard modifier button down.
@@ -73,6 +77,8 @@ namespace AzManipulatorTestFramework
virtual void CameraStateImpl(const AzFramework::CameraState& cameraState) = 0;
virtual void MouseLButtonDownImpl() = 0;
virtual void MouseLButtonUpImpl() = 0;
virtual void MouseMButtonDownImpl() = 0;
virtual void MouseMButtonUpImpl() = 0;
virtual void MouseLButtonDoubleClickImpl() = 0;
virtual void MousePositionImpl(const AzFramework::ScreenPoint& position) = 0;
virtual void KeyboardModifierDownImpl(const AzToolsFramework::ViewportInteraction::KeyboardModifier& keyModifier) = 0;
@@ -183,6 +189,22 @@ namespace AzManipulatorTestFramework
return static_cast<DerivedDispatcherT*>(this);
}
template<typename DerivedDispatcherT>
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseMButtonDown()
{
Log("Mouse middle button down");
MouseMButtonDownImpl();
return static_cast<DerivedDispatcherT*>(this);
}
template<typename DerivedDispatcherT>
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseMButtonUp()
{
Log("Mouse middle button up");
MouseMButtonUpImpl();
return static_cast<DerivedDispatcherT*>(this);
}
template<typename DerivedDispatcherT>
DerivedDispatcherT* ActionDispatcher<DerivedDispatcherT>::MouseLButtonDoubleClick()
{
@@ -8,6 +8,7 @@
#pragma once
#include <AzFramework/Viewport/ViewportId.h>
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
#include <AzToolsFramework/UnitTest/AzToolsFrameworkTestHelpers.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
@@ -40,7 +41,7 @@ namespace AzManipulatorTestFramework
//! Set the angular step.
virtual void SetAngularStep(float step) = 0;
//! Get the viewport id.
virtual int GetViewportId() const = 0;
virtual AzFramework::ViewportId GetViewportId() const = 0;
//! Updates the visibility state.
//! Updates which entities are currently visible given the current camera state.
virtual void UpdateVisibility() = 0;
@@ -30,7 +30,7 @@ namespace AzManipulatorTestFramework
private:
AZStd::shared_ptr<CustomManipulatorManager> m_customManager;
std::unique_ptr<ViewportInteraction> m_viewportInteraction;
std::unique_ptr<DirectCallManipulatorManager> m_manipulatorManager;
AZStd::unique_ptr<ViewportInteraction> m_viewportInteraction;
AZStd::unique_ptr<DirectCallManipulatorManager> m_manipulatorManager;
};
} // namespace AzManipulatorTestFramework
@@ -25,7 +25,7 @@ namespace AzManipulatorTestFramework
using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
public:
explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction);
explicit ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction);
~ImmediateModeActionDispatcher();
//! Clear the current event state.
@@ -55,13 +55,15 @@ namespace AzManipulatorTestFramework
AZStd::chrono::milliseconds EditorViewportInputTimeNow() override;
protected:
// ActionDispatcher ...
// ActionDispatcher overrides ...
void SetSnapToGridImpl(bool enabled) override;
void SetStickySelectImpl(bool enabled) override;
void GridSizeImpl(float size) override;
void CameraStateImpl(const AzFramework::CameraState& cameraState) override;
void MouseLButtonDownImpl() override;
void MouseLButtonUpImpl() override;
void MouseMButtonDownImpl() override;
void MouseMButtonUpImpl() override;
void MouseLButtonDoubleClickImpl() override;
void MousePositionImpl(const AzFramework::ScreenPoint& position) override;
void KeyboardModifierDownImpl(const KeyboardModifier& keyModifier) override;
@@ -82,7 +84,7 @@ namespace AzManipulatorTestFramework
const MouseInteractionEvent* GetMouseInteractionEvent() const;
mutable AZStd::unique_ptr<MouseInteractionEvent> m_event;
ManipulatorViewportInteraction& m_viewportManipulatorInteraction;
ManipulatorViewportInteraction& m_manipulatorViewportInteraction;
//! Current time that ticks up after each call to EditorViewportInputTimeNow.
AZStd::chrono::milliseconds m_timeNow = AZStd::chrono::milliseconds(0);
@@ -33,7 +33,7 @@ namespace AzManipulatorTestFramework
void SetAngularSnapping(bool enabled) override;
void SetGridSize(float size) override;
void SetAngularStep(float step) override;
int GetViewportId() const override;
AzFramework::ViewportId GetViewportId() const override;
void UpdateVisibility() override;
void SetStickySelect(bool enabled) override;
AZ::Vector3 DefaultEditorCameraPosition() const override;
@@ -60,9 +60,10 @@ namespace AzManipulatorTestFramework
void FindVisibleEntities(AZStd::vector<AZ::EntityId>& visibleEntities) override;
private:
static constexpr AzFramework::ViewportId m_viewportId = 1234; //!< Arbitrary viewport id for manipulator tests.
AzFramework::EntityVisibilityQuery m_entityVisibilityQuery;
AZStd::unique_ptr<NullDebugDisplayRequests> m_nullDebugDisplayRequests;
const int m_viewportId = 1234; // Arbitrary viewport id for manipulator tests
AzFramework::CameraState m_cameraState;
bool m_gridSnapping = false;
bool m_angularSnapping = false;
@@ -29,8 +29,8 @@ namespace AzManipulatorTestFramework
using KeyboardModifier = AzToolsFramework::ViewportInteraction::KeyboardModifier;
using MouseInteractionEvent = AzToolsFramework::ViewportInteraction::MouseInteractionEvent;
ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& viewportManipulatorInteraction)
: m_viewportManipulatorInteraction(viewportManipulatorInteraction)
ImmediateModeActionDispatcher::ImmediateModeActionDispatcher(ManipulatorViewportInteraction& manipulatorViewportInteraction)
: m_manipulatorViewportInteraction(manipulatorViewportInteraction)
{
AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect();
AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Handler::BusConnect();
@@ -48,34 +48,34 @@ namespace AzManipulatorTestFramework
// mouse down and mouse up event, to match the editor behavior we insert this event
// to ensure the tests are simulating the same environment as the editor
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move;
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
}
void ImmediateModeActionDispatcher::SetSnapToGridImpl(const bool enabled)
{
m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSnapping(enabled);
m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSnapping(enabled);
}
void ImmediateModeActionDispatcher::SetStickySelectImpl(const bool enabled)
{
m_viewportManipulatorInteraction.GetViewportInteraction().SetStickySelect(enabled);
m_manipulatorViewportInteraction.GetViewportInteraction().SetStickySelect(enabled);
}
void ImmediateModeActionDispatcher::GridSizeImpl(const float size)
{
m_viewportManipulatorInteraction.GetViewportInteraction().SetGridSize(size);
m_manipulatorViewportInteraction.GetViewportInteraction().SetGridSize(size);
}
void ImmediateModeActionDispatcher::CameraStateImpl(const AzFramework::CameraState& cameraState)
{
m_viewportManipulatorInteraction.GetViewportInteraction().SetCameraState(cameraState);
m_manipulatorViewportInteraction.GetViewportInteraction().SetCameraState(cameraState);
}
void ImmediateModeActionDispatcher::MouseLButtonDownImpl()
{
ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down;
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
// the mouse position will be the same as the previous event, thus the delta will be 0
MouseMoveAfterButton();
}
@@ -83,17 +83,35 @@ namespace AzManipulatorTestFramework
void ImmediateModeActionDispatcher::MouseLButtonUpImpl()
{
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
// the mouse position will be the same as the previous event, thus the delta will be 0
MouseMoveAfterButton();
}
void ImmediateModeActionDispatcher::MouseMButtonDownImpl()
{
ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle);
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Down;
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
// the mouse position will be the same as the previous event, thus the delta will be 0
MouseMoveAfterButton();
}
void ImmediateModeActionDispatcher::MouseMButtonUpImpl()
{
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Up;
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Middle);
// the mouse position will be the same as the previous event, thus the delta will be 0
MouseMoveAfterButton();
}
void ImmediateModeActionDispatcher::MouseLButtonDoubleClickImpl()
{
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::DoubleClick;
ToggleOn(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
ToggleOff(GetMouseInteractionEvent()->m_mouseInteraction.m_mouseButtons.m_mouseButtons, MouseButton::Left);
// the mouse position will be the same as the previous event, thus the delta will be 0
MouseMoveAfterButton();
@@ -101,10 +119,10 @@ namespace AzManipulatorTestFramework
void ImmediateModeActionDispatcher::MousePositionImpl(const AzFramework::ScreenPoint& position)
{
const auto cameraState = m_viewportManipulatorInteraction.GetViewportInteraction().GetCameraState();
const auto cameraState = m_manipulatorViewportInteraction.GetViewportInteraction().GetCameraState();
GetMouseInteractionEvent()->m_mouseInteraction.m_mousePick = BuildMousePick(position, cameraState);
GetMouseInteractionEvent()->m_mouseEvent = AzToolsFramework::ViewportInteraction::MouseEvent::Move;
m_viewportManipulatorInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
m_manipulatorViewportInteraction.GetManipulatorManager().ConsumeMouseInteractionEvent(*m_event);
}
void ImmediateModeActionDispatcher::KeyboardModifierDownImpl(const KeyboardModifier& keyModifier)
@@ -144,7 +162,7 @@ namespace AzManipulatorTestFramework
{
m_event = AZStd::unique_ptr<MouseInteractionEvent>(AZStd::make_unique<MouseInteractionEvent>());
m_event->m_mouseInteraction.m_interactionId.m_viewportId =
m_viewportManipulatorInteraction.GetViewportInteraction().GetViewportId();
m_manipulatorViewportInteraction.GetViewportInteraction().GetViewportId();
}
return m_event.get();
@@ -178,12 +196,12 @@ namespace AzManipulatorTestFramework
void ImmediateModeActionDispatcher::ExpectManipulatorBeingInteractedImpl()
{
EXPECT_TRUE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted());
EXPECT_TRUE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted());
}
void ImmediateModeActionDispatcher::ExpectManipulatorNotBeingInteractedImpl()
{
EXPECT_FALSE(m_viewportManipulatorInteraction.GetManipulatorManager().ManipulatorBeingInteracted());
EXPECT_FALSE(m_manipulatorViewportInteraction.GetManipulatorManager().ManipulatorBeingInteracted());
}
ImmediateModeActionDispatcher* ImmediateModeActionDispatcher::ResetEvent()
@@ -135,20 +135,20 @@ namespace AzManipulatorTestFramework
m_angularStep = step;
}
int ViewportInteraction::GetViewportId() const
AzFramework::ViewportId ViewportInteraction::GetViewportId() const
{
return m_viewportId;
}
AZ::Vector3 ViewportInteraction::ViewportScreenToWorld([[maybe_unused]] const AzFramework::ScreenPoint& screenPosition)
{
return AZ::Vector3::CreateZero();
return AzFramework::ScreenToWorld(screenPosition, m_cameraState);
}
AzToolsFramework::ViewportInteraction::ProjectedViewportRay ViewportInteraction::ViewportScreenToWorldRay(
[[maybe_unused]] const AzFramework::ScreenPoint& screenPosition)
{
return {};
return AzToolsFramework::ViewportInteraction::ViewportScreenToWorldRay(m_cameraState, screenPosition);
}
float ViewportInteraction::DeviceScalingFactor()
@@ -53,14 +53,14 @@ static void OptimizedSetParent(QWidget* widget, QWidget* parent)
namespace AzQtComponents
{
static FancyDockingDropZoneConstants g_FancyDockingConstants;
static const FancyDockingDropZoneConstants g_FancyDockingConstants;
// Constant for the threshold in pixels for snapping to edges while dragging for docking
static const int g_snapThresholdInPixels = 15;
static QString g_minimizeButtonObjectName = "minimizeButton";
static QString g_maximizeButtonObjectName = "maximizeButton";
static QString g_closeButtonObjectName = "closeButton";
static const QString MinimizeButtonObjectName = QStringLiteral("minimizeButton");
static const QString MaximizeButtonObjectName = QStringLiteral("maximizeButton");
static const QString CloseButtonObjectName = QStringLiteral("closeButton");
static Qt::Orientation orientation(Qt::DockWidgetArea area)
{
@@ -460,7 +460,7 @@ namespace AzQtComponents
// Minimize Icon
QAction* minimizeAction = new QAction(tr("Minimize"));
minimizeAction->setObjectName(g_minimizeButtonObjectName);
minimizeAction->setObjectName(MinimizeButtonObjectName);
connect(minimizeAction, &QAction::triggered, this, [titleBar]() {
titleBar->handleMinimize();
@@ -470,7 +470,7 @@ namespace AzQtComponents
// Maximize Icon
QAction* maximizeAction = new QAction(tr("Maximize"));
maximizeAction->setObjectName(g_maximizeButtonObjectName);
maximizeAction->setObjectName(MaximizeButtonObjectName);
connect(maximizeAction, &QAction::triggered, this, [titleBar]() {
titleBar->handleMaximize();
@@ -480,7 +480,7 @@ namespace AzQtComponents
// Close Icon
QAction* closeAction = new QAction(tr("Close"));
closeAction->setObjectName(g_closeButtonObjectName);
closeAction->setObjectName(CloseButtonObjectName);
connect(closeAction, &QAction::triggered, this, [titleBar]() {
titleBar->handleClose();
@@ -19,7 +19,7 @@
namespace AzQtComponents
{
static FancyDockingDropZoneConstants g_Constants;
static const FancyDockingDropZoneConstants g_Constants;
FancyDockingDropZoneConstants::FancyDockingDropZoneConstants()
{
@@ -27,7 +27,7 @@ AZ_POP_DISABLE_WARNING
namespace AzQtComponents
{
static const char clearButtonActionNameC[] = "_q_qlineeditclearaction";
static const QString ClearButtonActionNameC = QStringLiteral("_q_qlineeditclearaction");
struct BrowseEdit::InternalData
{
@@ -263,7 +263,7 @@ namespace AzQtComponents
auto lineEdit = browseEdit->m_data->m_lineEdit;
LineEdit::polish(style, lineEdit, lineEditConfig);
QAction* action = lineEdit->findChild<QAction*>(clearButtonActionNameC);
QAction* action = lineEdit->findChild<QAction*>(ClearButtonActionNameC);
if (action)
{
QStyleOptionFrame option;
@@ -284,7 +284,7 @@ namespace AzQtComponents
auto lineEdit = browseEdit->m_data->m_lineEdit;
LineEdit::unpolish(style, lineEdit, lineEditConfig);
QAction* action = lineEdit->findChild<QAction*>(clearButtonActionNameC);
QAction* action = lineEdit->findChild<QAction*>(ClearButtonActionNameC);
if (action)
{
QStyleOptionFrame option;
@@ -32,7 +32,7 @@ namespace AzQtComponents
namespace Internal
{
const char* OverlayWidgetLayer::s_layerStyle = "background-color:rgba(0, 0, 0, 179)";
static const QString LayerStyle = QStringLiteral("background-color:rgba(0, 0, 0, 179)");
OverlayWidgetLayer::OverlayWidgetLayer(OverlayWidget* parent, QWidget* centerWidget, QWidget* breakoutWidget,
const char* title, const OverlayWidgetButtonList& buttons)
@@ -66,7 +66,7 @@ namespace AzQtComponents
if (breakoutWidget)
{
setStyleSheet(s_layerStyle);
setStyleSheet(LayerStyle);
setLayout(new QHBoxLayout());
// close the overlay if either dependent widget is destroyed
@@ -100,7 +100,7 @@ namespace AzQtComponents
}
else
{
setStyleSheet(s_layerStyle);
setStyleSheet(LayerStyle);
}
AddButtons(*m_ui.data(), buttons, parent == nullptr);
}
@@ -59,8 +59,6 @@ namespace AzQtComponents
bool eventFilter(QObject* object, QEvent* event) override;
static const char* s_layerStyle;
QVector<Button> m_buttons;
QScopedPointer<Ui::OverlayWidgetLayer> m_ui;
OverlayWidget* m_parent;
@@ -213,12 +213,10 @@ namespace AzQtComponents
// rectangle drawing.
if (qTableView || qListView)
{
int hHdr = 0;
int vHdr = 0;
if (qTableView)
{
hHdr = qTableView->horizontalHeader()->isVisible() ? qTableView->horizontalHeader()->height() : 0;
vHdr = qTableView->verticalHeader()->isVisible() ? qTableView->verticalHeader()->width() : 0;
}
@@ -13,8 +13,6 @@
#define AZ_TRAIT_UNIT_TEST_ENTITY_ID_GEN_TEST_COUNT 10000
#define AZ_TRAIT_UNIT_TEST_DILLER_TRIGGER_EVENT_COUNT 100000
#define AZ_TRAIT_DISABLE_ALL_SAVE_DATA_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_AP_CONNECTION_TESTS true
#define AZ_TRAIT_DISABLE_FAILED_ASSET_LOAD_TESTS true
@@ -10,6 +10,7 @@
#include <AzCore/base.h>
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Vector2.h>
class CVegetationMap;
struct CVegetationInstance;
@@ -54,6 +54,7 @@
#include <AzToolsFramework/API/ComponentEntityObjectBus.h>
#include <AzToolsFramework/API/EditorCameraBus.h>
#include <AzToolsFramework/API/ViewPaneOptions.h>
#include <AzToolsFramework/API/ViewportEditorModeTrackerNotificationBus.h>
#include <AzToolsFramework/Entity/EditorEntitySearchComponent.h>
#include <AzToolsFramework/Entity/EditorEntitySortComponent.h>
#include <AzToolsFramework/Entity/EditorEntityModelComponent.h>
@@ -385,6 +386,7 @@ namespace AzToolsFramework
ComponentModeFramework::ComponentModeDelegate::Reflect(context);
ViewportInteraction::ViewportInteractionReflect(context);
ViewportEditorModeNotifications::Reflect(context);
Camera::EditorCameraRequests::Reflect(context);
AzToolsFramework::EditorTransformComponentSelectionRequests::Reflect(context);
@@ -30,6 +30,7 @@ namespace AzToolsFramework
connect(m_filterModel, &QAbstractItemModel::rowsRemoved, this, &AssetBrowserTableModel::UpdateTableModelMaps);
connect(m_filterModel, &QAbstractItemModel::layoutChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps);
connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::beginResetModel);
connect(m_filterModel, &AssetBrowserFilterModel::filterChanged, this, &AssetBrowserTableModel::UpdateTableModelMaps);
connect(m_filterModel, &QAbstractItemModel::dataChanged, this, &AssetBrowserTableModel::SourceDataChanged);
}
@@ -6,7 +6,7 @@
*
*/
#include <AzToolsFramework/Input/QtEventToAzInputManager.h>
#include <AzToolsFramework/Input/QtEventToAzInputMapper.h>
#include <AzCore/std/smart_ptr/make_shared.h>
@@ -84,12 +84,12 @@ namespace AzToolsFramework
break;
case State::Translating:
{
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Left() &&
if (mouseInteraction.m_mouseInteraction.m_mouseButtons.Middle() &&
mouseInteraction.m_mouseEvent == ViewportInteraction::MouseEvent::Down &&
mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Shift() &&
mouseInteraction.m_mouseInteraction.m_keyboardModifiers.Ctrl())
{
SnapVerticesToTerrain(mouseInteraction);
SnapVerticesToSurface(mouseInteraction);
return true;
}
@@ -109,29 +109,23 @@ namespace AzToolsFramework
}
template<typename Vertex>
void EditorVertexSelectionBase<Vertex>::SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
void EditorVertexSelectionBase<Vertex>::SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction)
{
ScopedUndoBatch surfaceSnapUndo("Snap to Surface");
ScopedUndoBatch::MarkEntityDirty(GetEntityId());
const int viewportId = mouseInteraction.m_mouseInteraction.m_interactionId.m_viewportId;
// get unsnapped terrain position (world space)
AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero();
;
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
worldSurfacePosition, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
// get unsnapped surface position (world space)
const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(
viewportId, mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates, EditorPickRayLength,
GetDefaultEntityPlacementDistance());
AZ::Transform worldFromLocal;
AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
const AZ::Transform localFromWorld = worldFromLocal.GetInverse();
// convert to local space - snap if enabled
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
const AZ::Vector3 localFinalSurfacePosition = gridSnapParams.m_gridSnap
? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocal, viewportId, gridSnapParams.m_gridSize)
: localFromWorld.TransformPoint(worldSurfacePosition);
// convert to local space
const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition);
SetSelectedPosition(localFinalSurfacePosition);
OnEntityComponentPropertyChanged(GetEntityComponentIdPair());
@@ -171,7 +171,7 @@ namespace AzToolsFramework
//! Snap the selected vertices to the terrain.
//! Note: With a multi-selection the manipulator will be translated to the picked
//! terrain position with all vertices moved relative to it.
void SnapVerticesToTerrain(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
void SnapVerticesToSurface(const ViewportInteraction::MouseInteractionEvent& mouseInteraction);
//! The Actions provided by the EditorVertexSelection while it is active.
//! e.g. Vertex deletion, duplication etc.
@@ -110,30 +110,6 @@ namespace AzToolsFramework
return unsnappedPosition + CalculateSnappedOffset(unsnappedPosition, snapAxes, snapAxesCount, size);
}
AZ::Vector3 CalculateSnappedTerrainPosition(
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, const int viewportId, const float size)
{
const AZ::Transform localFromWorld = worldFromLocal.GetInverse();
const AZ::Vector3 localSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition);
// snap in xy plane
AZ::Vector3 localSnappedSurfacePosition = localSurfacePosition +
CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisX(), size) +
CalculateSnappedOffset(localSurfacePosition, AZ::Vector3::CreateAxisY(), size);
// find terrain height at xy snapped location
float terrainHeight = 0.0f;
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
terrainHeight, viewportId, &ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::TerrainHeight,
Vector3ToVector2(worldFromLocal.TransformPoint(localSnappedSurfacePosition)));
// set snapped z value to terrain height
AZ::Vector3 localTerrainHeight = localFromWorld.TransformPoint(AZ::Vector3(0.0f, 0.0f, terrainHeight));
localSnappedSurfacePosition.SetZ(localTerrainHeight.GetZ());
return localSnappedSurfacePosition;
}
bool GridSnapping(const int viewportId)
{
bool snapping = false;
@@ -63,11 +63,6 @@ namespace AzToolsFramework
AZ::Vector3 CalculateSnappedPosition(
const AZ::Vector3& unsnappedPosition, const AZ::Vector3* snapAxes, size_t snapAxesCount, float size);
//! For a given point on the terrain, calculate the closest xy position snapped to the grid
//! (z position is aligned to terrain height, not snapped to z grid)
AZ::Vector3 CalculateSnappedTerrainPosition(
const AZ::Vector3& worldSurfacePosition, const AZ::Transform& worldFromLocal, int viewportId, float size);
//! Wrapper for grid snapping and grid size bus calls.
GridSnapParameters GridSnapSettings(int viewportId);
@@ -10,6 +10,7 @@
#include <AzToolsFramework/Manipulators/ManipulatorSnapping.h>
#include <AzToolsFramework/Manipulators/ManipulatorView.h>
#include <AzToolsFramework/ViewportSelection/EditorSelectionUtil.h>
namespace AzToolsFramework
{
@@ -17,28 +18,16 @@ namespace AzToolsFramework
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
const AZ::Vector3& localStartPosition,
const bool snapping,
const float gridSize,
const int viewportId)
[[maybe_unused]] const bool snapping,
[[maybe_unused]] const float gridSize,
[[maybe_unused]] const int viewportId)
{
const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal);
const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse();
const AZ::Vector3 localFinalSurfacePosition = snapping
// note: gridSize is not scaled by scaleRecip here as localStartPosition is
// unscaled itself so the position returned by CalculateSnappedTerrainPosition
// must be in the same space (if localStartPosition were also scaled, gridSize
// would need to be multiplied by scaleRecip)
? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize)
: localFromWorldUniform.TransformPoint(worldSurfacePosition);
// delta/offset between initial vertex position and terrain pick position
const AZ::Vector3 localSurfaceOffset = localFinalSurfacePosition - localStartPosition;
const AZ::Transform localFromWorld = worldFromLocal.GetInverse();
StartInternal startInternal;
startInternal.m_snapOffset = localSurfaceOffset;
startInternal.m_localPosition = localStartPosition + localSurfaceOffset;
startInternal.m_localHitPosition = localFromWorldUniform.TransformVector(worldSurfacePosition);
startInternal.m_snapOffset = AZ::Vector3::CreateZero();
startInternal.m_localPosition = localStartPosition;
startInternal.m_localHitPosition = localFromWorld.TransformPoint(worldSurfacePosition);
return startInternal;
}
@@ -46,26 +35,19 @@ namespace AzToolsFramework
const StartInternal& startInternal,
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
const bool snapping,
const float gridSize,
[[maybe_unused]] const bool snapping,
[[maybe_unused]] const float gridSize,
const ViewportInteraction::KeyboardModifiers keyboardModifiers,
const int viewportId)
[[maybe_unused]] const int viewportId)
{
const AZ::Transform worldFromLocalUniform = AzToolsFramework::TransformUniformScale(worldFromLocal);
const AZ::Transform localFromWorldUniform = worldFromLocalUniform.GetInverse();
const float scaleRecip = ScaleReciprocal(worldFromLocalUniform);
const AZ::Vector3 localFinalSurfacePosition = snapping
? CalculateSnappedTerrainPosition(worldSurfacePosition, worldFromLocalUniform, viewportId, gridSize * scaleRecip)
: localFromWorldUniform.TransformPoint(worldSurfacePosition);
const AZ::Transform localFromWorld = worldFromLocal.GetInverse();
const AZ::Vector3 localFinalSurfacePosition = localFromWorld.TransformPoint(worldSurfacePosition);
Action action;
action.m_start.m_localPosition = startInternal.m_localPosition;
action.m_start.m_snapOffset = startInternal.m_snapOffset;
action.m_start.m_snapOffset = AZ::Vector3::CreateZero();
action.m_current.m_localOffset = localFinalSurfacePosition - startInternal.m_localPosition;
// record what modifier keys are held during this action
action.m_modifiers = keyboardModifiers;
action.m_modifiers = keyboardModifiers; // record what modifier keys are held during this action
return action;
}
@@ -78,12 +60,16 @@ namespace AzToolsFramework
{
SetSpace(worldFromLocal);
AttachLeftMouseDownImpl();
// only cast rays against objects (entities/meshes etc.) we can actually see
m_rayRequest.m_onlyVisible = true;
}
void SurfaceManipulator::InstallLeftMouseDownCallback(const MouseActionCallback& onMouseDownCallback)
{
m_onLeftMouseDownCallback = onMouseDownCallback;
}
void SurfaceManipulator::InstallLeftMouseUpCallback(const MouseActionCallback& onMouseUpCallback)
{
m_onLeftMouseUpCallback = onMouseUpCallback;
@@ -95,17 +81,30 @@ namespace AzToolsFramework
}
void SurfaceManipulator::OnLeftMouseDownImpl(
const ViewportInteraction::MouseInteraction& interaction, float /*rayIntersectionDistance*/)
const ViewportInteraction::MouseInteraction& interaction, [[maybe_unused]] float rayIntersectionDistance)
{
const AZ::Transform worldFromLocalUniformScale = TransformUniformScale(GetSpace());
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId;
AZ::Vector3 worldSurfacePosition;
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
interaction.m_mousePick.m_screenCoordinates);
const auto& entityComponentIdPairs = EntityComponentIdPairs();
m_rayRequest.m_entityFilter.m_ignoreEntities.clear();
m_rayRequest.m_entityFilter.m_ignoreEntities.reserve(entityComponentIdPairs.size());
AZStd::transform(
entityComponentIdPairs.begin(), entityComponentIdPairs.end(),
AZStd::inserter(m_rayRequest.m_entityFilter.m_ignoreEntities, m_rayRequest.m_entityFilter.m_ignoreEntities.begin()),
[](const AZ::EntityComponentIdPair& entityComponentIdPair)
{
return entityComponentIdPair.GetEntityId();
});
// calculate the start and end of the ray
RefreshRayRequest(
m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates),
EditorPickRayLength);
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance());
m_startInternal = CalculateManipulationDataStart(
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(), gridSnapParams.m_gridSnap, gridSnapParams.m_gridSize,
@@ -123,17 +122,14 @@ namespace AzToolsFramework
{
if (m_onLeftMouseUpCallback)
{
AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero();
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
interaction.m_mousePick.m_screenCoordinates);
const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId;
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance());
m_onLeftMouseUpCallback(CalculateManipulationDataAction(
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap,
gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, interaction.m_interactionId.m_viewportId));
gridSnapParams.m_gridSize, interaction.m_keyboardModifiers, viewportId));
}
}
@@ -141,13 +137,15 @@ namespace AzToolsFramework
{
if (m_onMouseMoveCallback)
{
AZ::Vector3 worldSurfacePosition = AZ::Vector3::CreateZero();
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
interaction.m_mousePick.m_screenCoordinates);
const AzFramework::ViewportId viewportId = interaction.m_interactionId.m_viewportId;
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
// update the start and end of the ray
RefreshRayRequest(
m_rayRequest, ViewportInteraction::ViewportScreenToWorldRay(viewportId, interaction.m_mousePick.m_screenCoordinates),
EditorPickRayLength);
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
const AZ::Vector3 worldSurfacePosition = FindClosestPickIntersection(m_rayRequest, GetDefaultEntityPlacementDistance());
m_onMouseMoveCallback(CalculateManipulationDataAction(
m_startInternal, TransformUniformScale(GetSpace()), worldSurfacePosition, gridSnapParams.m_gridSnap,
@@ -11,6 +11,7 @@
#include "BaseManipulator.h"
#include <AzCore/Memory/SystemAllocator.h>
#include <AzFramework/Render/GeometryIntersectionStructures.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
namespace AzToolsFramework
@@ -58,10 +59,12 @@ namespace AzToolsFramework
Start m_start;
Current m_current;
ViewportInteraction::KeyboardModifiers m_modifiers;
AZ::Vector3 LocalPosition() const
{
return m_start.m_localPosition + m_current.m_localOffset;
}
AZ::Vector3 LocalPositionOffset() const
{
return m_current.m_localOffset;
@@ -106,6 +109,9 @@ namespace AzToolsFramework
MouseActionCallback m_onLeftMouseUpCallback = nullptr;
MouseActionCallback m_onMouseMoveCallback = nullptr;
//! Cached ray request initialized at mouse down and updated during mouse move.
AzFramework::RenderGeometry::RayRequest m_rayRequest;
static StartInternal CalculateManipulationDataStart(
const AZ::Transform& worldFromLocal,
const AZ::Vector3& worldSurfacePosition,
@@ -34,10 +34,12 @@ namespace AzToolsFramework::Prefab
PrefabPublicNotificationBus::Handler::BusConnect();
AZ::Interface<PrefabFocusInterface>::Register(this);
AZ::Interface<PrefabFocusPublicInterface>::Register(this);
PrefabFocusPublicRequestBus::Handler::BusConnect();
}
PrefabFocusHandler::~PrefabFocusHandler()
{
PrefabFocusPublicRequestBus::Handler::BusDisconnect();
AZ::Interface<PrefabFocusPublicInterface>::Unregister(this);
AZ::Interface<PrefabFocusInterface>::Unregister(this);
PrefabPublicNotificationBus::Handler::BusDisconnect();
@@ -45,6 +47,18 @@ namespace AzToolsFramework::Prefab
EditorEntityInfoNotificationBus::Handler::BusDisconnect();
}
void PrefabFocusHandler::Reflect(AZ::ReflectContext* context)
{
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context); behaviorContext)
{
behaviorContext->EBus<PrefabFocusPublicRequestBus>("PrefabFocusPublicRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Category, "Prefab")
->Attribute(AZ::Script::Attributes::Module, "prefab")
->Event("FocusOnOwningPrefab", &PrefabFocusPublicInterface::FocusOnOwningPrefab);
}
}
void PrefabFocusHandler::InitializeEditorInterfaces()
{
m_containerEntityInterface = AZ::Interface<ContainerEntityInterface>::Get();
@@ -30,8 +30,8 @@ namespace AzToolsFramework::Prefab
//! Handles Prefab Focus mode, determining which prefab file entity changes will target.
class PrefabFocusHandler final
: private PrefabFocusInterface
, private PrefabFocusPublicInterface
: public PrefabFocusPublicRequestBus::Handler
, private PrefabFocusInterface
, private PrefabPublicNotificationBus::Handler
, private EditorEntityContextNotificationBus::Handler
, private EditorEntityInfoNotificationBus::Handler
@@ -42,13 +42,15 @@ namespace AzToolsFramework::Prefab
PrefabFocusHandler();
~PrefabFocusHandler();
static void Reflect(AZ::ReflectContext* context);
// PrefabFocusInterface overrides ...
void InitializeEditorInterfaces() override;
PrefabFocusOperationResult FocusOnPrefabInstanceOwningEntityId(AZ::EntityId entityId) override;
TemplateId GetFocusedPrefabTemplateId(AzFramework::EntityContextId entityContextId) const override;
InstanceOptionalReference GetFocusedPrefabInstance(AzFramework::EntityContextId entityContextId) const override;
// PrefabFocusPublicInterface overrides ...
// PrefabFocusPublicInterface and PrefabFocusPublicRequestBus overrides ...
PrefabFocusOperationResult FocusOnOwningPrefab(AZ::EntityId entityId) override;
PrefabFocusOperationResult FocusOnParentOfFocusedPrefab(AzFramework::EntityContextId entityContextId) override;
PrefabFocusOperationResult FocusOnPathIndex(AzFramework::EntityContextId entityContextId, int index) override;
@@ -58,4 +58,18 @@ namespace AzToolsFramework::Prefab
virtual const int GetPrefabFocusPathLength(AzFramework::EntityContextId entityContextId) const = 0;
};
/**
* The primary purpose of this bus is to facilitate writing automated tests for prefab focus mode.
* If you would like to integrate prefabs focus mode into your system, please call PrefabFocusPublicInterface
* for better performance.
*/
class PrefabFocusPublicRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
};
using PrefabFocusPublicRequestBus = AZ::EBus<PrefabFocusPublicInterface, PrefabFocusPublicRequests>;
} // namespace AzToolsFramework::Prefab
@@ -60,6 +60,7 @@ namespace AzToolsFramework
AzToolsFramework::Prefab::PrefabConversionUtils::PrefabCatchmentProcessor::Reflect(context);
AzToolsFramework::Prefab::PrefabConversionUtils::EditorInfoRemover::Reflect(context);
PrefabPublicRequestHandler::Reflect(context);
PrefabFocusHandler::Reflect(context);
PrefabLoader::Reflect(context);
PrefabSystemScriptingHandler::Reflect(context);
@@ -23,7 +23,6 @@ namespace AzToolsFramework
// save 2k at a time :( need a better way to do this.
AZStd::size_t pos = 0;
AZStd::size_t remaining = m_windowState.size();
AZ::u8* charData = (AZ::u8*)windowState.begin();
while (remaining > 0)
{
@@ -31,7 +30,6 @@ namespace AzToolsFramework
m_serializableWindowState.push_back();
m_serializableWindowState.back().assign((AZ::u8*)windowState.begin() + pos, (AZ::u8*)windowState.begin() + pos + bytes_this_gulp);
pos += bytes_this_gulp;
charData += bytes_this_gulp;
remaining -= bytes_this_gulp;
}
}
@@ -169,6 +169,10 @@ namespace AzToolsFramework
{
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&PropertyEditorGUIMessages::Bus::Events::RequestWrite, newCtrl);
});
this->connect(newCtrl, &PropertyControl::editingFinished, this, [newCtrl]()
{
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&PropertyEditorGUIMessages::Bus::Handler::OnEditingFinished, newCtrl);
});
// note: Qt automatically disconnects objects from each other when either end is destroyed, no need to worry about delete.
// Set the value range to that of ValueType as clamped to the range of QtWidgetValueType
@@ -1201,8 +1201,6 @@ namespace AzToolsFramework
.arg((item->parent() == nullptr) ? item->m_entity->GetName().c_str() : GetNodeDisplayName(*item->m_node).c_str()));
}
SliceTargetTreeItem* parent = nullptr;
AZStd::vector<SliceAssetPtr> validSliceAssets = GetValidTargetAssetsForField(*item);
// For the selected item populate the tree of all valid slice targets.
@@ -1274,7 +1272,6 @@ namespace AzToolsFramework
selectButton->setChecked(true);
}
parent = sliceItem;
++level;
}
}
@@ -64,23 +64,12 @@ namespace AzToolsFramework
return circleBoundWidth;
}
AZ::Vector3 FindClosestPickIntersection(
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, const float rayLength, const float defaultDistance)
AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, const float defaultDistance)
{
using AzToolsFramework::ViewportInteraction::ViewportInteractionRequestBus;
AzToolsFramework::ViewportInteraction::ProjectedViewportRay viewportRay{};
ViewportInteractionRequestBus::EventResult(
viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
AzFramework::RenderGeometry::RayRequest ray;
ray.m_startWorldPosition = viewportRay.origin;
ray.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
ray.m_onlyVisible = true;
AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult;
AzFramework::RenderGeometry::IntersectorBus::EventResult(
renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(),
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray);
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, rayRequest);
// attempt a ray intersection with any visible mesh and return the intersection position if successful
if (renderGeometryIntersectionResult)
@@ -89,7 +78,32 @@ namespace AzToolsFramework
}
else
{
return viewportRay.origin + viewportRay.direction * defaultDistance;
const AZ::Vector3 rayDirection = (rayRequest.m_endWorldPosition - rayRequest.m_startWorldPosition).GetNormalized();
return rayRequest.m_startWorldPosition + rayDirection * defaultDistance;
}
}
void RefreshRayRequest(
AzFramework::RenderGeometry::RayRequest& rayRequest,
const ViewportInteraction::ProjectedViewportRay& viewportRay,
const float rayLength)
{
AZ_Assert(rayLength > 0.0f, "Invalid ray length passed to RefreshRayRequest");
rayRequest.m_startWorldPosition = viewportRay.origin;
rayRequest.m_endWorldPosition = viewportRay.origin + viewportRay.direction * rayLength;
}
AZ::Vector3 FindClosestPickIntersection(
const AzFramework::ViewportId viewportId,
const AzFramework::ScreenPoint& screenPoint,
const float rayLength,
const float defaultDistance)
{
AzFramework::RenderGeometry::RayRequest ray;
ray.m_onlyVisible = true; // only consider visible objects
RefreshRayRequest(ray, ViewportInteraction::ViewportScreenToWorldRay(viewportId, screenPoint), rayLength);
return FindClosestPickIntersection(ray, defaultDistance);
}
} // namespace AzToolsFramework
@@ -15,13 +15,19 @@
#include <AzFramework/Viewport/CameraState.h>
#include <AzFramework/Viewport/ClickDetector.h>
#include <AzFramework/Viewport/ViewportId.h>
#include <AzFramework/Viewport/ViewportScreen.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Viewport/ViewportTypes.h>
namespace AzFramework
{
struct ScreenPoint;
}
namespace RenderGeometry
{
struct RayRequest;
}
} // namespace AzFramework
namespace AzToolsFramework
{
@@ -177,6 +183,26 @@ namespace AzToolsFramework
//! Type to inherit to implement ViewportInteractionRequests.
using ViewportInteractionRequestBus = AZ::EBus<ViewportInteractionRequests, ViewportEBusTraits>;
//! Utility function to return a viewport ray.
inline ProjectedViewportRay ViewportScreenToWorldRay(
const AzFramework::CameraState& cameraState, const AzFramework::ScreenPoint& screenPoint)
{
const AZ::Vector3 rayOrigin = AzFramework::ScreenToWorld(screenPoint, cameraState);
const AZ::Vector3 rayDirection = (rayOrigin - cameraState.m_position).GetNormalized();
return AzToolsFramework::ViewportInteraction::ProjectedViewportRay{ rayOrigin, rayDirection };
}
//! Utility function to return a viewport ray using the ViewportInteractionRequestBus.
inline ProjectedViewportRay ViewportScreenToWorldRay(
const AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint)
{
ProjectedViewportRay viewportRay{};
ViewportInteractionRequestBus::EventResult(
viewportRay, viewportId, &ViewportInteractionRequestBus::Events::ViewportScreenToWorldRay, screenPoint);
return viewportRay;
}
//! Interface to return only viewport specific settings (e.g. snapping).
class ViewportSettingsRequests
{
@@ -228,10 +254,6 @@ namespace AzToolsFramework
class MainEditorViewportInteractionRequests
{
public:
//! Given a point in screen space, return the terrain position in world space.
virtual AZ::Vector3 PickTerrain(const AzFramework::ScreenPoint& point) = 0;
//! Return the terrain height given a world position in 2d (xy plane).
virtual float TerrainHeight(const AZ::Vector2& position) = 0;
//! Is the user holding a modifier key to move the manipulator space from local to world.
virtual bool ShowingWorldSpace() = 0;
//! Return the widget to use as the parent for the viewport context menu.
@@ -337,9 +359,18 @@ namespace AzToolsFramework
//! Performs an intersection test against meshes in the scene, if there is a hit (the ray intersects
//! a mesh), that position is returned, otherwise a point projected defaultDistance from the
//! origin of the ray will be returned.
//! @note The intersection will only consider visible objects.
AZ::Vector3 FindClosestPickIntersection(
AzFramework::ViewportId viewportId, const AzFramework::ScreenPoint& screenPoint, float rayLength, float defaultDistance);
//! Overload of FindClosestPickIntersection taking a RenderGeometry::RayRequest directly.
//! @note rayRequest must contain a valid ray/line segment (start/endWorldPosition must not be at the same position).
AZ::Vector3 FindClosestPickIntersection(const AzFramework::RenderGeometry::RayRequest& rayRequest, float defaultDistance);
//! Update the in/out parameter rayRequest based on the latest viewport ray.
void RefreshRayRequest(
AzFramework::RenderGeometry::RayRequest& rayRequest, const ViewportInteraction::ProjectedViewportRay& viewportRay, float rayLength);
//! Maps a mouse interaction event to a ClickDetector event.
//! @note Function only cares about up or down events, all other events are mapped to Nil (ignored).
AzFramework::ClickDetector::ClickEvent ClickDetectorEventFromViewportInteraction(
@@ -9,6 +9,7 @@
#include "EditorSelectionUtil.h"
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Math/Aabb.h>
#include <AzCore/Math/IntersectSegment.h>
@@ -16,8 +17,21 @@
#include <AzToolsFramework/API/ComponentEntitySelectionBus.h>
#include <AzToolsFramework/Viewport/ViewportMessages.h>
AZ_CVAR(
float,
ed_defaultEntityPlacementDistance,
10.0f,
nullptr,
AZ::ConsoleFunctorFlags::Null,
"The default distance to place an entity from the camera if no intersection is found");
namespace AzToolsFramework
{
float GetDefaultEntityPlacementDistance()
{
return ed_defaultEntityPlacementDistance;
}
AZ::Vector3 CalculateCenterOffset(const AZ::EntityId entityId, const EditorTransformComponentSelectionRequests::Pivot pivot)
{
if (Centered(pivot))

Some files were not shown because too many files have changed in this diff Show More