merging from main
This commit is contained in:
@@ -239,8 +239,13 @@ namespace AZ
|
||||
return;
|
||||
}
|
||||
|
||||
CheckReady();
|
||||
m_initComplete = true;
|
||||
|
||||
// *After* setting initComplete to true, check to see if the assets are already ready.
|
||||
// This check needs to wait until after setting initComplete because if they *are* ready, we want the final call to
|
||||
// RemoveWaitingAsset to trigger the OnAssetContainerReady/Canceled event. If we call CheckReady() *before* setting
|
||||
// initComplete, if all the assets are ready, the event will never get triggered.
|
||||
CheckReady();
|
||||
}
|
||||
|
||||
bool AssetContainer::IsReady() const
|
||||
|
||||
@@ -1454,32 +1454,48 @@ namespace AZ
|
||||
//=========================================================================
|
||||
void AssetManager::ReloadAssetFromData(const Asset<AssetData>& asset)
|
||||
{
|
||||
AZ_Assert(asset.Get(), "Asset data for reload is missing.");
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
|
||||
AZ_Assert(m_assets.find(asset.GetId()) != m_assets.end(), "Unable to reload asset %s because its not in the AssetManager's asset list.", asset.ToString<AZStd::string>().c_str());
|
||||
AZ_Assert(m_assets.find(asset.GetId()) == m_assets.end() || asset->RTTI_GetType() == m_assets.find(asset.GetId())->second->RTTI_GetType(),
|
||||
"New and old data types are mismatched!");
|
||||
bool shouldAssignAssetData = false;
|
||||
|
||||
auto found = m_assets.find(asset.GetId());
|
||||
if ((found == m_assets.end()) || (asset->RTTI_GetType() != found->second->RTTI_GetType()))
|
||||
{
|
||||
return; // this will just lead to crashes down the line and the above asserts cover this.
|
||||
}
|
||||
AZ_Assert(asset.Get(), "Asset data for reload is missing.");
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> assetLock(m_assetMutex);
|
||||
AZ_Assert(
|
||||
m_assets.find(asset.GetId()) != m_assets.end(),
|
||||
"Unable to reload asset %s because it's not in the AssetManager's asset list.", asset.ToString<AZStd::string>().c_str());
|
||||
AZ_Assert(
|
||||
m_assets.find(asset.GetId()) == m_assets.end() ||
|
||||
asset->RTTI_GetType() == m_assets.find(asset.GetId())->second->RTTI_GetType(),
|
||||
"New and old data types are mismatched!");
|
||||
|
||||
AssetData* newData = asset.Get();
|
||||
|
||||
if (found->second != newData)
|
||||
{
|
||||
// Notify users that we are about to change asset
|
||||
AssetBus::Event(asset.GetId(), &AssetBus::Events::OnAssetPreReload, asset);
|
||||
|
||||
// Resolve the asset handler and account for the new asset instance.
|
||||
auto found = m_assets.find(asset.GetId());
|
||||
if ((found == m_assets.end()) || (asset->RTTI_GetType() != found->second->RTTI_GetType()))
|
||||
{
|
||||
AssetHandlerMap::iterator handlerIt = m_handlers.find(newData->GetType());
|
||||
AZ_Assert(handlerIt != m_handlers.end(), "No handler was registered for this asset [type:%s id:%s]!",
|
||||
newData->GetType().ToString<AZ::OSString>().c_str(), newData->GetId().ToString<AZ::OSString>().c_str());
|
||||
return; // this will just lead to crashes down the line and the above asserts cover this.
|
||||
}
|
||||
|
||||
AssetData* newData = asset.Get();
|
||||
|
||||
if (found->second != newData)
|
||||
{
|
||||
// Notify users that we are about to change asset
|
||||
AssetBus::Event(asset.GetId(), &AssetBus::Events::OnAssetPreReload, asset);
|
||||
|
||||
// Resolve the asset handler and account for the new asset instance.
|
||||
{
|
||||
AssetHandlerMap::iterator handlerIt = m_handlers.find(newData->GetType());
|
||||
AZ_Assert(
|
||||
handlerIt != m_handlers.end(), "No handler was registered for this asset [type:%s id:%s]!",
|
||||
newData->GetType().ToString<AZ::OSString>().c_str(), newData->GetId().ToString<AZ::OSString>().c_str());
|
||||
}
|
||||
|
||||
shouldAssignAssetData = true;
|
||||
}
|
||||
}
|
||||
|
||||
// We specifically perform this outside of the m_assetMutex lock so that the lock isn't held at the point that
|
||||
// OnAssetReload is triggered inside of AssignAssetData. Otherwise, we open up a high potential for deadlocks.
|
||||
if (shouldAssignAssetData)
|
||||
{
|
||||
AssignAssetData(asset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,27 +142,44 @@ namespace AZ
|
||||
void SetBasis(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ);
|
||||
//! @}
|
||||
|
||||
Matrix3x3 operator*(const Matrix3x3& rhs) const;
|
||||
|
||||
//! Calculates (this->GetTranspose() * rhs).
|
||||
Matrix3x3 TransposedMultiply(const Matrix3x3& rhs) const;
|
||||
|
||||
//! Post-multiplies the matrix by a vector.
|
||||
Vector3 operator*(const Vector3& rhs) const;
|
||||
|
||||
Matrix3x3 operator+(const Matrix3x3& rhs) const;
|
||||
Matrix3x3 operator-(const Matrix3x3& rhs) const;
|
||||
|
||||
Matrix3x3 operator*(float multiplier) const;
|
||||
Matrix3x3 operator/(float divisor) const;
|
||||
|
||||
Matrix3x3 operator-() const;
|
||||
|
||||
Matrix3x3& operator*=(const Matrix3x3& rhs);
|
||||
//! Operator for matrix-matrix addition.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x3 operator+(const Matrix3x3& rhs) const;
|
||||
Matrix3x3& operator+=(const Matrix3x3& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for matrix-matrix substraction.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x3 operator-(const Matrix3x3& rhs) const;
|
||||
Matrix3x3& operator-=(const Matrix3x3& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for matrix-matrix multiplication.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x3 operator*(const Matrix3x3& rhs) const;
|
||||
Matrix3x3& operator*=(const Matrix3x3& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for multiplying all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x3 operator*(float multiplier) const;
|
||||
Matrix3x3& operator*=(float multiplier);
|
||||
//! @}
|
||||
|
||||
//! Operator for dividing all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x3 operator/(float divisor) const;
|
||||
Matrix3x3& operator/=(float divisor);
|
||||
//! @}
|
||||
|
||||
//! Operator for negating all matrix's elements
|
||||
[[nodiscard]] Matrix3x3 operator-() const;
|
||||
|
||||
bool operator==(const Matrix3x3& rhs) const;
|
||||
bool operator!=(const Matrix3x3& rhs) const;
|
||||
@@ -187,7 +204,10 @@ namespace AZ
|
||||
//! @}
|
||||
|
||||
//! Gets the scale part of the transformation, i.e. the length of the scale components.
|
||||
Vector3 RetrieveScale() const;
|
||||
[[nodiscard]] Vector3 RetrieveScale() const;
|
||||
|
||||
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
|
||||
[[nodiscard]] Vector3 RetrieveScaleSq() const;
|
||||
|
||||
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
|
||||
Vector3 ExtractScale();
|
||||
@@ -195,6 +215,9 @@ namespace AZ
|
||||
//! Quick multiplication by a scale matrix, equivalent to m*=Matrix3x3::CreateScale(scale).
|
||||
void MultiplyByScale(const Vector3& scale);
|
||||
|
||||
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
|
||||
[[nodiscard]] Matrix3x3 GetReciprocalScaled() const;
|
||||
|
||||
//! Polar decomposition, M=U*H, U is orthogonal (unitary) and H is symmetric (hermitian).
|
||||
//! This function returns the orthogonal part only
|
||||
Matrix3x3 GetPolarDecomposition() const;
|
||||
@@ -241,7 +264,9 @@ namespace AZ
|
||||
//! Note that this is not the usual multiplication order for transformations.
|
||||
Vector3& operator*=(Vector3& lhs, const Matrix3x3& rhs);
|
||||
|
||||
//! Pre-multiplies the matrix by a scalar.
|
||||
Matrix3x3 operator*(float lhs, const Matrix3x3& rhs);
|
||||
}
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
#include <AzCore/Math/Matrix3x3.inl>
|
||||
|
||||
@@ -392,14 +392,6 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const
|
||||
{
|
||||
Matrix3x3 result;
|
||||
Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::TransposedMultiply(const Matrix3x3& rhs) const
|
||||
{
|
||||
Matrix3x3 result;
|
||||
@@ -416,51 +408,12 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator+(const Matrix3x3& rhs) const
|
||||
{
|
||||
return Matrix3x3(Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
|
||||
, Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
|
||||
, Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const
|
||||
{
|
||||
return Matrix3x3(Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
|
||||
, Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
|
||||
, Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const
|
||||
{
|
||||
const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier);
|
||||
return Matrix3x3(Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec)
|
||||
, Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec)
|
||||
, Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const
|
||||
{
|
||||
const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor);
|
||||
return Matrix3x3(Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec)
|
||||
, Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec)
|
||||
, Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const
|
||||
{
|
||||
const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat();
|
||||
return Matrix3x3(Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue())
|
||||
, Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue())
|
||||
, Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue()));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& rhs)
|
||||
{
|
||||
*this = *this * rhs;
|
||||
return *this;
|
||||
return Matrix3x3
|
||||
(
|
||||
Simd::Vec3::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec3::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec3::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -471,6 +424,17 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-(const Matrix3x3& rhs) const
|
||||
{
|
||||
return Matrix3x3
|
||||
(
|
||||
Simd::Vec3::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec3::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec3::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator-=(const Matrix3x3& rhs)
|
||||
{
|
||||
*this = *this - rhs;
|
||||
@@ -478,6 +442,33 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(const Matrix3x3& rhs) const
|
||||
{
|
||||
Matrix3x3 result;
|
||||
Simd::Vec3::Mat3x3Multiply(GetSimdValues(), rhs.GetSimdValues(), result.GetSimdValues());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(const Matrix3x3& rhs)
|
||||
{
|
||||
*this = *this * rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator*(float multiplier) const
|
||||
{
|
||||
const Simd::Vec3::FloatType mulVec = Simd::Vec3::Splat(multiplier);
|
||||
return Matrix3x3
|
||||
(
|
||||
Simd::Vec3::Mul(m_rows[0].GetSimdValue(), mulVec),
|
||||
Simd::Vec3::Mul(m_rows[1].GetSimdValue(), mulVec),
|
||||
Simd::Vec3::Mul(m_rows[2].GetSimdValue(), mulVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator*=(float multiplier)
|
||||
{
|
||||
*this = *this * multiplier;
|
||||
@@ -485,6 +476,18 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator/(float divisor) const
|
||||
{
|
||||
const Simd::Vec3::FloatType divVec = Simd::Vec3::Splat(divisor);
|
||||
return Matrix3x3
|
||||
(
|
||||
Simd::Vec3::Div(m_rows[0].GetSimdValue(), divVec),
|
||||
Simd::Vec3::Div(m_rows[1].GetSimdValue(), divVec),
|
||||
Simd::Vec3::Div(m_rows[2].GetSimdValue(), divVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3& Matrix3x3::operator/=(float divisor)
|
||||
{
|
||||
*this = *this / divisor;
|
||||
@@ -492,6 +495,18 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::operator-() const
|
||||
{
|
||||
const Simd::Vec3::FloatType zeroVec = Simd::Vec3::ZeroFloat();
|
||||
return Matrix3x3
|
||||
(
|
||||
Simd::Vec3::Sub(zeroVec, m_rows[0].GetSimdValue()),
|
||||
Simd::Vec3::Sub(zeroVec, m_rows[1].GetSimdValue()),
|
||||
Simd::Vec3::Sub(zeroVec, m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Matrix3x3::operator==(const Matrix3x3& rhs) const
|
||||
{
|
||||
return (Simd::Vec3::CmpAllEq(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
|
||||
@@ -552,6 +567,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x3::RetrieveScaleSq() const
|
||||
{
|
||||
return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq());
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x3::ExtractScale()
|
||||
{
|
||||
const Vector3 x = GetBasisX();
|
||||
@@ -584,6 +605,14 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 Matrix3x3::GetReciprocalScaled() const
|
||||
{
|
||||
Matrix3x3 result = *this;
|
||||
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE void Matrix3x3::GetPolarDecomposition(Matrix3x3* orthogonalOut, Matrix3x3* symmetricOut) const
|
||||
{
|
||||
*orthogonalOut = GetPolarDecomposition();
|
||||
@@ -679,8 +708,6 @@ namespace AZ
|
||||
|
||||
AZ_MATH_INLINE Matrix3x3 operator*(float lhs, const Matrix3x3& rhs)
|
||||
{
|
||||
const Simd::Vec3::FloatType lhsVec = Simd::Vec3::Splat(lhs);
|
||||
const Simd::Vec3::FloatType* rows = rhs.GetSimdValues();
|
||||
return Matrix3x3(Simd::Vec3::Mul(lhsVec, rows[0]), Simd::Vec3::Mul(lhsVec, rows[1]), Simd::Vec3::Mul(lhsVec, rows[2]));
|
||||
return rhs * lhs;
|
||||
}
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -225,11 +225,38 @@ namespace AZ
|
||||
//! Sets the three basis vectors and the translation.
|
||||
void SetBasisAndTranslation(const Vector3& basisX, const Vector3& basisY, const Vector3& basisZ, const Vector3& translation);
|
||||
|
||||
//! Operator for matrix-matrix multiplication.
|
||||
[[nodiscard]] Matrix3x4 operator*(const Matrix3x4& rhs) const;
|
||||
//! Operator for matrix-matrix addition.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator+(const Matrix3x4& rhs) const;
|
||||
Matrix3x4& operator+=(const Matrix3x4& rhs);
|
||||
//! @}
|
||||
|
||||
//! Compound assignment operator for matrix-matrix multiplication.
|
||||
//! Operator for matrix-matrix substraction.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator-(const Matrix3x4& rhs) const;
|
||||
Matrix3x4& operator-=(const Matrix3x4& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for matrix-matrix multiplication.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator*(const Matrix3x4& rhs) const;
|
||||
Matrix3x4& operator*=(const Matrix3x4& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for multiplying all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator*(float multiplier) const;
|
||||
Matrix3x4& operator*=(float multiplier);
|
||||
//! @}
|
||||
|
||||
//! Operator for dividing all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix3x4 operator/(float divisor) const;
|
||||
Matrix3x4& operator/=(float divisor);
|
||||
//! @}
|
||||
|
||||
//! Operator for negating all matrix's elements
|
||||
[[nodiscard]] Matrix3x4 operator-() const;
|
||||
|
||||
//! Operator for transforming a Vector3.
|
||||
[[nodiscard]] Vector3 operator*(const Vector3& rhs) const;
|
||||
@@ -274,12 +301,18 @@ namespace AZ
|
||||
//! Gets the scale part of the transformation (the length of the basis vectors).
|
||||
[[nodiscard]] Vector3 RetrieveScale() const;
|
||||
|
||||
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
|
||||
[[nodiscard]] Vector3 RetrieveScaleSq() const;
|
||||
|
||||
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
|
||||
Vector3 ExtractScale();
|
||||
|
||||
//! Multiplies the basis vectors of the matrix by the elements of the scale specified.
|
||||
void MultiplyByScale(const Vector3& scale);
|
||||
|
||||
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
|
||||
[[nodiscard]] Matrix3x4 GetReciprocalScaled() const;
|
||||
|
||||
//! Tests if the 3x3 part of the matrix is orthogonal.
|
||||
bool IsOrthogonal(float tolerance = Constants::Tolerance) const;
|
||||
|
||||
@@ -335,6 +368,10 @@ namespace AZ
|
||||
|
||||
Vector4 m_rows[RowCount];
|
||||
};
|
||||
|
||||
//! Pre-multiplies the matrix by a scalar.
|
||||
Matrix3x4 operator*(float lhs, const Matrix3x4& rhs);
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
#include <AzCore/Math/Matrix3x4.inl>
|
||||
|
||||
@@ -472,6 +472,42 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator+(const Matrix3x4& rhs) const
|
||||
{
|
||||
return Matrix3x4
|
||||
(
|
||||
Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator+=(const Matrix3x4& rhs)
|
||||
{
|
||||
*this = *this + rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-(const Matrix3x4& rhs) const
|
||||
{
|
||||
return Matrix3x4
|
||||
(
|
||||
Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator-=(const Matrix3x4& rhs)
|
||||
{
|
||||
*this = *this - rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(const Matrix3x4& rhs) const
|
||||
{
|
||||
Matrix3x4 result;
|
||||
@@ -487,6 +523,56 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator*(float multiplier) const
|
||||
{
|
||||
const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier);
|
||||
return Matrix3x4
|
||||
(
|
||||
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec),
|
||||
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec),
|
||||
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float multiplier)
|
||||
{
|
||||
*this = *this * multiplier;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator/(float divisor) const
|
||||
{
|
||||
const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor);
|
||||
return Matrix3x4
|
||||
(
|
||||
Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec),
|
||||
Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec),
|
||||
Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator/=(float divisor)
|
||||
{
|
||||
*this = *this / divisor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::operator-() const
|
||||
{
|
||||
const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat();
|
||||
return Matrix3x4
|
||||
(
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x4::operator*(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3
|
||||
@@ -583,6 +669,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x4::RetrieveScaleSq() const
|
||||
{
|
||||
return Vector3(GetColumn(0).GetLengthSq(), GetColumn(1).GetLengthSq(), GetColumn(2).GetLengthSq());
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix3x4::ExtractScale()
|
||||
{
|
||||
const Vector3 scale = RetrieveScale();
|
||||
@@ -600,6 +692,14 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 Matrix3x4::GetReciprocalScaled() const
|
||||
{
|
||||
Matrix3x4 result = *this;
|
||||
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE void Matrix3x4::Orthogonalize()
|
||||
{
|
||||
*this = GetOrthogonalized();
|
||||
@@ -660,4 +760,10 @@ namespace AZ
|
||||
{
|
||||
return reinterpret_cast<Simd::Vec4::FloatType*>(m_rows);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix3x4 operator*(float lhs, const Matrix3x4& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -171,14 +171,38 @@ namespace AZ
|
||||
void SetTranslation(const Vector3& v);
|
||||
//! @}
|
||||
|
||||
Matrix4x4 operator+(const Matrix4x4& rhs) const;
|
||||
//! Operator for matrix-matrix addition.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix4x4 operator+(const Matrix4x4& rhs) const;
|
||||
Matrix4x4& operator+=(const Matrix4x4& rhs);
|
||||
//! @}
|
||||
|
||||
Matrix4x4 operator-(const Matrix4x4& rhs) const;
|
||||
//! Operator for matrix-matrix substraction.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix4x4 operator-(const Matrix4x4& rhs) const;
|
||||
Matrix4x4& operator-=(const Matrix4x4& rhs);
|
||||
//! @}
|
||||
|
||||
Matrix4x4 operator*(const Matrix4x4& rhs) const;
|
||||
//! Operator for matrix-matrix multiplication.
|
||||
//! @{
|
||||
[[nodiscard]] Matrix4x4 operator*(const Matrix4x4& rhs) const;
|
||||
Matrix4x4& operator*=(const Matrix4x4& rhs);
|
||||
//! @}
|
||||
|
||||
//! Operator for multiplying all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix4x4 operator*(float multiplier) const;
|
||||
Matrix4x4& operator*=(float multiplier);
|
||||
//! @}
|
||||
|
||||
//! Operator for dividing all matrix's elements with a scalar
|
||||
//! @{
|
||||
[[nodiscard]] Matrix4x4 operator/(float divisor) const;
|
||||
Matrix4x4& operator/=(float divisor);
|
||||
//! @}
|
||||
|
||||
//! Operator for negating all matrix's elements
|
||||
[[nodiscard]] Matrix4x4 operator-() const;
|
||||
|
||||
//! Post-multiplies the matrix by a vector.
|
||||
//! Assumes that the w-component of the Vector3 is 1.0.
|
||||
@@ -222,7 +246,10 @@ namespace AZ
|
||||
//! @}
|
||||
|
||||
//! Gets the scale part of the transformation, i.e. the length of the scale components.
|
||||
Vector3 RetrieveScale() const;
|
||||
[[nodiscard]] Vector3 RetrieveScale() const;
|
||||
|
||||
//! Gets the squared scale part of the transformation (the squared length of the basis vectors).
|
||||
[[nodiscard]] Vector3 RetrieveScaleSq() const;
|
||||
|
||||
//! Gets the scale part of the transformation as in RetrieveScale, and also removes this scaling from the matrix.
|
||||
Vector3 ExtractScale();
|
||||
@@ -230,6 +257,9 @@ namespace AZ
|
||||
//! Quick multiplication by a scale matrix, equivalent to m*=Matrix4x4::CreateScale(scale).
|
||||
void MultiplyByScale(const Vector3& scale);
|
||||
|
||||
//! Returns a matrix with the reciprocal scale, keeping the same rotation and translation.
|
||||
[[nodiscard]] Matrix4x4 GetReciprocalScaled() const;
|
||||
|
||||
bool IsClose(const Matrix4x4& rhs, float tolerance = Constants::Tolerance) const;
|
||||
|
||||
bool operator==(const Matrix4x4& rhs) const;
|
||||
@@ -270,6 +300,10 @@ namespace AZ
|
||||
//! Pre-multiplies the matrix by a vector in-place.
|
||||
//! Note that this is not the usual multiplication order for transformations.
|
||||
Vector4& operator*=(Vector4& lhs, const Matrix4x4& rhs);
|
||||
}
|
||||
|
||||
//! Pre-multiplies the matrix by a scalar.
|
||||
Matrix4x4 operator*(float lhs, const Matrix4x4& rhs);
|
||||
|
||||
} // namespace AZ
|
||||
|
||||
#include <AzCore/Math/Matrix4x4.inl>
|
||||
|
||||
@@ -480,20 +480,12 @@ namespace AZ
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator+(const Matrix4x4& rhs) const
|
||||
{
|
||||
return Matrix4x4
|
||||
( Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
|
||||
, Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
|
||||
, Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
, Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()));
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const
|
||||
{
|
||||
return Matrix4x4
|
||||
( Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue())
|
||||
, Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue())
|
||||
, Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue())
|
||||
, Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue()));
|
||||
(
|
||||
Simd::Vec4::Add(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Add(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Add(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()),
|
||||
Simd::Vec4::Add(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator+=(const Matrix4x4& rhs)
|
||||
@@ -502,6 +494,18 @@ namespace AZ
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-(const Matrix4x4& rhs) const
|
||||
{
|
||||
return Matrix4x4
|
||||
(
|
||||
Simd::Vec4::Sub(m_rows[0].GetSimdValue(), rhs.m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Sub(m_rows[1].GetSimdValue(), rhs.m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Sub(m_rows[2].GetSimdValue(), rhs.m_rows[2].GetSimdValue()),
|
||||
Simd::Vec4::Sub(m_rows[3].GetSimdValue(), rhs.m_rows[3].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator-=(const Matrix4x4& rhs)
|
||||
{
|
||||
*this = *this - rhs;
|
||||
@@ -523,6 +527,59 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator*(float multiplier) const
|
||||
{
|
||||
const Simd::Vec4::FloatType mulVec = Simd::Vec4::Splat(multiplier);
|
||||
return Matrix4x4
|
||||
(
|
||||
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), mulVec),
|
||||
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), mulVec),
|
||||
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), mulVec),
|
||||
Simd::Vec4::Mul(m_rows[3].GetSimdValue(), mulVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator*=(float multiplier)
|
||||
{
|
||||
*this = *this * multiplier;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator/(float divisor) const
|
||||
{
|
||||
const Simd::Vec4::FloatType divVec = Simd::Vec4::Splat(divisor);
|
||||
return Matrix4x4
|
||||
(
|
||||
Simd::Vec4::Div(m_rows[0].GetSimdValue(), divVec),
|
||||
Simd::Vec4::Div(m_rows[1].GetSimdValue(), divVec),
|
||||
Simd::Vec4::Div(m_rows[2].GetSimdValue(), divVec),
|
||||
Simd::Vec4::Div(m_rows[3].GetSimdValue(), divVec)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4& Matrix4x4::operator/=(float divisor)
|
||||
{
|
||||
*this = *this / divisor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::operator-() const
|
||||
{
|
||||
const Simd::Vec4::FloatType zeroVec = Simd::Vec4::ZeroFloat();
|
||||
return Matrix4x4
|
||||
(
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[0].GetSimdValue()),
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[1].GetSimdValue()),
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[2].GetSimdValue()),
|
||||
Simd::Vec4::Sub(zeroVec, m_rows[3].GetSimdValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix4x4::operator*(const Vector3& rhs) const
|
||||
{
|
||||
return Vector3(Simd::Vec4::Mat4x4TransformPoint3(GetSimdValues(), rhs.GetSimdValue()));
|
||||
@@ -595,6 +652,12 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix4x4::RetrieveScaleSq() const
|
||||
{
|
||||
return Vector3(GetBasisX().GetLengthSq(), GetBasisY().GetLengthSq(), GetBasisZ().GetLengthSq());
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Vector3 Matrix4x4::ExtractScale()
|
||||
{
|
||||
Vector4 x = GetBasisX();
|
||||
@@ -619,6 +682,14 @@ namespace AZ
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 Matrix4x4::GetReciprocalScaled() const
|
||||
{
|
||||
Matrix4x4 result = *this;
|
||||
result.MultiplyByScale(RetrieveScaleSq().GetReciprocal());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE bool Matrix4x4::IsClose(const Matrix4x4& rhs, float tolerance) const
|
||||
{
|
||||
const Simd::Vec4::FloatType vecTolerance = Simd::Vec4::Splat(tolerance);
|
||||
@@ -702,4 +773,10 @@ namespace AZ
|
||||
lhs = lhs * rhs;
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AZ_MATH_INLINE Matrix4x4 operator*(float lhs, const Matrix4x4& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -816,7 +816,7 @@ namespace AZ
|
||||
template<size_t Index>
|
||||
static void ReflectUnpackMethodFold(BehaviorContext::ClassBuilder<ContainerType>& builder)
|
||||
{
|
||||
AZStd::string methodName = AZStd::string::format("Get%ld", Index);
|
||||
const AZStd::string methodName = AZStd::string::format("Get%zu", Index);
|
||||
builder->Method(methodName.data(), [](ContainerType& value) { return AZStd::get<Index>(value); })
|
||||
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
|
||||
->Attribute(AZ::ScriptCanvasAttributes::TupleGetFunctionIndex, Index)
|
||||
|
||||
@@ -97,7 +97,8 @@ namespace AZ
|
||||
return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
AZStd::string::format("Failed to retrieve rtti information for %s.", classData->m_name));
|
||||
}
|
||||
AZ_Assert(classData->m_azRtti->GetTypeId() == typeId, "Type id mismatch during deserialization of a json file. (%s vs %s)");
|
||||
AZ_Assert(classData->m_azRtti->GetTypeId() == typeId, "Type id mismatch during deserialization of a json file. (%s vs %s)",
|
||||
classData->m_azRtti->GetTypeId().ToString<AZStd::string>().c_str(), typeId.ToString<AZStd::string>().c_str());
|
||||
|
||||
void** objectPtr = reinterpret_cast<void**>(object);
|
||||
bool isNull = *objectPtr == nullptr;
|
||||
@@ -512,27 +513,24 @@ namespace AZ
|
||||
if (*object)
|
||||
{
|
||||
const AZ::Uuid& actualClassId = rtti.GetActualUuid(*object);
|
||||
if (actualClassId != objectType)
|
||||
const SerializeContext::ClassData* actualClassData = context.GetSerializeContext()->FindClassData(actualClassId);
|
||||
if (!actualClassData)
|
||||
{
|
||||
const SerializeContext::ClassData* actualClassData = context.GetSerializeContext()->FindClassData(actualClassId);
|
||||
if (!actualClassData)
|
||||
{
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
AZStd::string::format("Unable to find serialization information for type %s.", actualClassId.ToString<AZStd::string>().c_str()));
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
|
||||
AZStd::string::format("Unable to find serialization information for type %s.", actualClassId.ToString<AZStd::string>().c_str()));
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
|
||||
if (actualClassData->m_factory)
|
||||
{
|
||||
actualClassData->m_factory->Destroy(*object);
|
||||
*object = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Catastrophic,
|
||||
"Unable to find the factory needed to clear out the default value.");
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
if (actualClassData->m_factory)
|
||||
{
|
||||
actualClassData->m_factory->Destroy(*object);
|
||||
*object = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = context.Report(Tasks::RetrieveInfo, Outcomes::Catastrophic,
|
||||
"Unable to find the factory needed to clear out the default value.");
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
}
|
||||
status = ResultCode(Tasks::ReadField, Outcomes::Success);
|
||||
|
||||
@@ -38,6 +38,20 @@ namespace AZ
|
||||
};
|
||||
|
||||
//! Core class to handle serialization to and from json documents.
|
||||
//! The Json Serialization works by taking a default constructed object and then apply the information found in the JSON document
|
||||
//! on top of that object. This allows the Json Serialization to avoid storing default values and helps guarantee that the final
|
||||
//! object is in a valid state even if non-fatal issues are encountered.
|
||||
//! Note on containers: Containers such as vector or map are always considered to be empty even if there's entries in the provided
|
||||
//! default object. During deserialization entries will be appended to any existing values. A flag is provided to automatically
|
||||
//! clear containers during deserialization.
|
||||
//! Note on maps: If the key for map containers such as unordered_map can be interpret as a string the Json Serialization will use
|
||||
//! a JSON Object to store the data in instead of an array with key/value objects.
|
||||
//! Note on pointers: The Json Serialization assumes that are always constructed, so a default JSON value of "{}" is interpret as
|
||||
//! creating a new default instance even if the default value is a null pointer. A JSON Null needs to be explicitly stored in
|
||||
//! the JSON Document in order to default or explicitly set a pointer to null.
|
||||
//! Note on pointer memory: Objects created/destroyed by the Json Serialization for pointers require that the AZ_CLASS_ALLOCATOR is
|
||||
//! declared and the object is created using aznew or memory is allocated using azmalloc. Without these the application may
|
||||
//! crash if the Json Serialization tries to create or destroy an object pointed to by a pointer.
|
||||
class JsonSerialization final
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -23,13 +23,6 @@ namespace AZ
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
|
||||
if (IsExplicitDefault(inputValue))
|
||||
{
|
||||
// Do nothing if the input is an explicit default.
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed,
|
||||
"Default value for smart pointer requested so no change was made.");
|
||||
}
|
||||
|
||||
const SerializeContext::ClassData* containerClass = context.GetSerializeContext()->FindClassData(outputValueTypeId);
|
||||
if (!containerClass)
|
||||
{
|
||||
@@ -153,8 +146,7 @@ namespace AZ
|
||||
|
||||
if (defaultValue)
|
||||
{
|
||||
bool typesMatch = false;
|
||||
auto defaultInputCallback = [&defaultValue, &inputPtrType, &typesMatch]
|
||||
auto defaultInputCallback = [&defaultValue]
|
||||
(void* elementPtr, const Uuid&, const SerializeContext::ClassData*, const SerializeContext::ClassElement*)
|
||||
{
|
||||
defaultValue = elementPtr;
|
||||
@@ -164,11 +156,6 @@ namespace AZ
|
||||
}
|
||||
|
||||
JSR::ResultCode result = ContinueStoring(outputValue, inputValue, defaultValue, inputPtrType, context, Flags::ResolvePointer);
|
||||
if (result.GetOutcome() == JSR::Outcomes::DefaultsUsed)
|
||||
{
|
||||
outputValue = GetExplicitDefault();
|
||||
return context.Report(result, "Smart pointer used all defaults.");
|
||||
}
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ?
|
||||
"Successfully processed smart pointer." : "A problem occurred while processing a smart pointer.");
|
||||
}
|
||||
|
||||
@@ -330,4 +330,163 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// The AssetManagerStreamerImmediateCompletionTests class adjusts the asset loading to force it to complete immediately,
|
||||
// while still within the callstack for GetAsset(). This can be used to test various conditions in which the load thread
|
||||
// completes more rapidly than expected, and can expose subtle race conditions.
|
||||
// There are a few key things that this class does to make this work:
|
||||
// - The file I/O streamer is mocked
|
||||
// - The asset stream data is mocked to a 0-byte length for the asset so that the stream load will bypass the I/O streamer and
|
||||
// just immediately return completion.
|
||||
// - The number of JobManager threads is set to 0, forcing jobs to execute synchronously inline when they are started.
|
||||
// With these changes, GetAssetInternal() will queue the stream, which will immediately call the callback that creates LoadAssetJob,
|
||||
// which immediately executes in-place to process the asset due to the synchronous JobManager.
|
||||
// Note that if we just created the asset in a Ready state, most of the asset loading code is completely bypassed, and so we
|
||||
// wouldn't be able to test for race conditions in the AssetContainer.
|
||||
//
|
||||
// This class also unregisters the catalog and asset handler before shutting down the asset manager. This is done to catch
|
||||
// any outstanding asset references that exist due to loads not completing and cleaning up successfully.
|
||||
struct AssetManagerStreamerImmediateCompletionTests : public BaseAssetManagerTest,
|
||||
public AZ::Data::AssetCatalogRequestBus::Handler,
|
||||
public AZ::Data::AssetHandler,
|
||||
public AZ::Data::AssetCatalog
|
||||
{
|
||||
static inline const AZ::Uuid TestAssetId{"{E970B177-5F45-44EB-A2C4-9F29D9A0B2A2}"};
|
||||
static inline constexpr AZStd::string_view TestAssetPath = "test";
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
BaseAssetManagerTest::SetUp();
|
||||
AssetManager::Descriptor desc;
|
||||
AssetManager::Create(desc);
|
||||
|
||||
// Register the handler and catalog after creation, because we intend to destroy them before AssetManager destruction.
|
||||
// The specific asset we load is irrelevant, so register EmptyAsset.
|
||||
AZ::Data::AssetManager::Instance().RegisterHandler(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
AZ::Data::AssetManager::Instance().RegisterCatalog(this, AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
|
||||
// Intercept messages for finding assets by name so that we can mock out the asset we're loading.
|
||||
AZ::Data::AssetCatalogRequestBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
// Unregister before destroying AssetManager.
|
||||
// This will catch any assets that got stuck in a loading state without getting cleaned up.
|
||||
AZ::Data::AssetManager::Instance().UnregisterCatalog(this);
|
||||
AZ::Data::AssetManager::Instance().UnregisterHandler(this);
|
||||
|
||||
AZ::Data::AssetCatalogRequestBus::Handler::BusDisconnect();
|
||||
|
||||
AssetManager::Destroy();
|
||||
BaseAssetManagerTest::TearDown();
|
||||
}
|
||||
|
||||
size_t GetNumJobManagerThreads() const override
|
||||
{
|
||||
// Return 0 threads so that the Job Manager executes jobs synchronously inline. This lets us finish a load while still
|
||||
// in the callstack that initiates the load.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create a mock streamer instead of a real one, since we don't really want to load an asset.
|
||||
IO::IStreamer* CreateStreamer() override
|
||||
{
|
||||
m_mockStreamer = AZStd::make_unique<StreamerWrapper>();
|
||||
return &(m_mockStreamer->m_mockStreamer);
|
||||
}
|
||||
|
||||
void DestroyStreamer([[maybe_unused]] IO::IStreamer* streamer) override
|
||||
{
|
||||
m_mockStreamer = nullptr;
|
||||
}
|
||||
|
||||
// AssetHandler implementation
|
||||
|
||||
// Minimalist mock to create a new EmptyAsset with the desired asset ID.
|
||||
AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, [[maybe_unused]] const AZ::Data::AssetType& type) override
|
||||
{
|
||||
return new EmptyAsset(id);
|
||||
}
|
||||
|
||||
void DestroyAsset(AZ::Data::AssetPtr ptr) override
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
// The mocked-out Asset Catalog handles EmptyAsset types.
|
||||
void GetHandledAssetTypes(AZStd::vector<AZ::Data::AssetType>& assetTypes) override
|
||||
{
|
||||
assetTypes.push_back(AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
}
|
||||
|
||||
// This is a mocked-out load, so just immediately return completion without doing anything.
|
||||
AZ::Data::AssetHandler::LoadResult LoadAssetData(
|
||||
[[maybe_unused]] const AZ::Data::Asset<AZ::Data::AssetData>& asset,
|
||||
[[maybe_unused]] AZStd::shared_ptr<AZ::Data::AssetDataStream> stream,
|
||||
[[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
return AZ::Data::AssetHandler::LoadResult::LoadComplete;
|
||||
}
|
||||
|
||||
// AssetCatalogRequestBus implementation
|
||||
|
||||
// Minimalist mocks to provide our desired asset path or asset id
|
||||
AZStd::string GetAssetPathById([[maybe_unused]] const AZ::Data::AssetId& id) override
|
||||
{
|
||||
return TestAssetPath;
|
||||
}
|
||||
AZ::Data::AssetId GetAssetIdByPath(
|
||||
[[maybe_unused]] const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister,
|
||||
[[maybe_unused]] bool autoRegisterIfNotFound) override
|
||||
{
|
||||
return TestAssetId;
|
||||
}
|
||||
|
||||
// Return the mocked-out information for our test asset
|
||||
AZ::Data::AssetInfo GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& id) override
|
||||
{
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
assetInfo.m_assetId = TestAssetId;
|
||||
assetInfo.m_assetType = AZ::AzTypeInfo<EmptyAsset>::Uuid();
|
||||
assetInfo.m_relativePath = TestAssetPath;
|
||||
return assetInfo;
|
||||
}
|
||||
|
||||
// AssetCatalog implementation
|
||||
|
||||
// Set the mocked-out asset load to have a 0-byte length so that the load skips I/O and immediately returns success
|
||||
AZ::Data::AssetStreamInfo GetStreamInfoForLoad(
|
||||
[[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override
|
||||
{
|
||||
EXPECT_TRUE(type == AZ::AzTypeInfo<EmptyAsset>::Uuid());
|
||||
AZ::Data::AssetStreamInfo info;
|
||||
info.m_dataOffset = 0;
|
||||
info.m_streamName = TestAssetPath;
|
||||
info.m_dataLen = 0;
|
||||
info.m_streamFlags = AZ::IO::OpenMode::ModeRead;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<StreamerWrapper> m_mockStreamer;
|
||||
};
|
||||
|
||||
// This test will verify that even if the asset loading stream/job returns immediately, all of the loading
|
||||
// code works successfully. The test here is fairly simple - it just loads the asset and verifies that it
|
||||
// loaded successfully. The bulk of the test is really in the setup class above, where the load is forced
|
||||
// to complete immediately. Also, the true failure condition is caught in the setup class too, which is
|
||||
// the presence of any assets at the point that the asset handler is unregistered. If they're present, then
|
||||
// the immediate load wasn't truly successful, as it left around extra references to the asset that haven't
|
||||
// been cleaned up.
|
||||
TEST_F(AssetManagerStreamerImmediateCompletionTests, LoadAssetWithImmediateJobCompletion_WorksSuccessfully)
|
||||
{
|
||||
AZ::Data::AssetLoadParameters loadParams;
|
||||
|
||||
auto testAsset =
|
||||
AssetManager::Instance().GetAsset<EmptyAsset>(TestAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
EXPECT_TRUE(testAsset.IsReady());
|
||||
}
|
||||
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -24,6 +24,13 @@ namespace UnitTest
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(EmptyAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(EmptyAsset, "{098E3F7F-13AC-414B-9B4E-49B5AD1BD7FE}", AZ::Data::AssetData);
|
||||
|
||||
EmptyAsset(
|
||||
const AZ::Data::AssetId& assetId = AZ::Data::AssetId(),
|
||||
AZ::Data::AssetData::AssetStatus status = AZ::Data::AssetData::AssetStatus::NotLoaded)
|
||||
: AZ::Data::AssetData(assetId, status)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// EmptyAssetWithNoHandler: no data contained within, and no AssetHandler registered for this type
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AZTestShared/Math/MathTestHelpers.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
@@ -251,19 +252,19 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 * m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
|
||||
Matrix3x3 m4 = m1;
|
||||
m4 *= m2;
|
||||
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(Vector3(66.0f, 72.0f, 78.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(Vector3(156.0f, 171.0f, 186.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(Vector3(246.0f, 270.0f, 294.0f)));
|
||||
m3 = m1.TransposedMultiply(m2);
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(138.0f, 150.0f, 162.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(168.0f, 183.0f, 198.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(198.0f, 216.0f, 234.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(138.0f, 150.0f, 162.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(168.0f, 183.0f, 198.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(198.0f, 216.0f, 234.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestVectorMultiplication)
|
||||
@@ -277,11 +278,11 @@ namespace UnitTest
|
||||
m2.SetRow(1, 10.0f, 11.0f, 12.0f);
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 32.0f, 50.0f)));
|
||||
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 32.0f, 50.0f)));
|
||||
Vector3 v1(1.0f, 2.0f, 3.0f);
|
||||
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
EXPECT_THAT((v1 * m1), IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
v1 *= m1;
|
||||
AZ_TEST_ASSERT(v1.IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
EXPECT_THAT(v1, IsClose(Vector3(30.0f, 36.0f, 42.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestSum)
|
||||
@@ -296,15 +297,15 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 + m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestDifference)
|
||||
@@ -319,14 +320,14 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 - m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(-6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScalarMultiplication)
|
||||
@@ -341,18 +342,18 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 * 2.0f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScalarDivision)
|
||||
@@ -367,18 +368,32 @@ namespace UnitTest
|
||||
m2.SetRow(2, 13.0f, 14.0f, 15.0f);
|
||||
|
||||
Matrix3x3 m3 = m1 / 0.5f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
m3 = -m1;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector3(2.0f, 4.0f, 6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector3(8.0f, 10.0f, 12.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector3(14.0f, 16.0f, 18.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestNegation)
|
||||
{
|
||||
Matrix3x3 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f);
|
||||
m1.SetRow(1, 4.0f, 5.0f, 6.0f);
|
||||
m1.SetRow(2, 7.0f, 8.0f, 9.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-Matrix3x3::CreateZero(), IsClose(Matrix3x3::CreateZero()));
|
||||
|
||||
Matrix3x3 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(Vector3(-1.0f, -2.0f, -3.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(Vector3(-4.0f, -5.0f, -6.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(Vector3(-7.0f, -8.0f, -9.0f)));
|
||||
|
||||
Matrix3x3 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(Matrix3x3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestTranspose)
|
||||
@@ -425,11 +440,33 @@ namespace UnitTest
|
||||
TEST(MATH_Matrix3x3, TestScaleAccess)
|
||||
{
|
||||
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
AZ_TEST_ASSERT(m1.ExtractScale().IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3::CreateOne()));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
AZ_TEST_ASSERT(m1.RetrieveScale().IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestScaleSqAccess)
|
||||
{
|
||||
Matrix3x3 m1 = Matrix3x3::CreateRotationX(DegToRad(40.0f)) * Matrix3x3::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
|
||||
m1.ExtractScale();
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestReciprocalScaled)
|
||||
{
|
||||
Matrix3x3 orthogonalMatrix = Matrix3x3::CreateRotationX(DegToRad(40.0f));
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x3 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix3x3 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x3, TestPolarDecomposition)
|
||||
|
||||
@@ -467,21 +467,136 @@ namespace UnitTest
|
||||
EXPECT_THAT(matrix.Multiply3x3(axisDirection), IsClose(forwardDirection));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, MultiplyByMatrix3x4)
|
||||
TEST(MATH_Matrix3x4, TestMatrixMultiplication)
|
||||
{
|
||||
const AZ::Matrix3x4 matrix1 = AZ::Matrix3x4::CreateFromValue(1.2f);
|
||||
const AZ::Matrix3x4 matrix2 = AZ::Matrix3x4::CreateDiagonal(AZ::Vector3(1.3f, 1.5f, 0.4f));
|
||||
const AZ::Matrix3x4 matrix3 = AZ::Matrix3x4::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f));
|
||||
const AZ::Matrix3x4 matrix4 = AZ::Matrix3x4::CreateRotationX(-0.7f) * AZ::Matrix3x4::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f));
|
||||
AZ::Matrix3x4 matrix5 = matrix1;
|
||||
matrix5 *= matrix4;
|
||||
const AZ::Vector3 vector(1.9f, 2.3f, 0.2f);
|
||||
EXPECT_TRUE((matrix1 * (matrix2 * matrix3)).IsClose((matrix1 * matrix2) * matrix3));
|
||||
EXPECT_THAT((matrix3 * matrix4) * vector, IsClose(matrix3 * (matrix4 * vector)));
|
||||
EXPECT_TRUE((matrix2 * AZ::Matrix3x4::Identity()).IsClose(matrix2));
|
||||
EXPECT_TRUE((matrix3 * AZ::Matrix3x4::Identity()).IsClose(AZ::Matrix3x4::Identity() * matrix3));
|
||||
EXPECT_TRUE(matrix5.IsClose(matrix1 * matrix4));
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
AZ::Matrix3x4 m3 = m1 * m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
|
||||
AZ::Matrix3x4 m4 = m1;
|
||||
m4 *= m2;
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(AZ::Vector4(74.0f, 80.0f, 86.0f, 96.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(AZ::Vector4(206.0f, 224.0f, 242.0f, 268.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(AZ::Vector4(338.0f, 368.0f, 398.0f, 440.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestSum)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 + m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestDifference)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 - m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestScalarMultiplication)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 * 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestScalarDivision)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
AZ::Matrix3x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 / 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(AZ::Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(AZ::Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(AZ::Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, TestNegation)
|
||||
{
|
||||
AZ::Matrix3x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero()));
|
||||
|
||||
AZ::Matrix3x4 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(AZ::Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(AZ::Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(AZ::Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
|
||||
|
||||
AZ::Matrix3x4 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(AZ::Matrix3x4::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix3x4, MultiplyByVector3)
|
||||
@@ -652,6 +767,34 @@ namespace UnitTest
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScale(), IsClose(AZ::Vector3::CreateOne()));
|
||||
}
|
||||
|
||||
TEST_P(Matrix3x4ScaleFixture, ScaleSq)
|
||||
{
|
||||
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
|
||||
EXPECT_THAT(orthogonalMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
AZ::Matrix3x4 unscaledMatrix = orthogonalMatrix;
|
||||
unscaledMatrix.ExtractScale();
|
||||
EXPECT_THAT(unscaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scale * scale));
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(scaledMatrix.RetrieveScale() * scaledMatrix.RetrieveScale()));
|
||||
scaledMatrix.ExtractScale();
|
||||
EXPECT_THAT(scaledMatrix.RetrieveScaleSq(), IsClose(AZ::Vector3::CreateOne()));
|
||||
}
|
||||
|
||||
TEST_P(Matrix3x4ScaleFixture, GetReciprocalScaled)
|
||||
{
|
||||
const AZ::Matrix3x4 orthogonalMatrix = GetParam();
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix3x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix3x4 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(MATH_Matrix3x4, Matrix3x4ScaleFixture, ::testing::ValuesIn(MathTestData::OrthogonalMatrix3x4s));
|
||||
|
||||
TEST(MATH_Matrix3x4, IsOrthogonal)
|
||||
|
||||
@@ -246,16 +246,16 @@ namespace UnitTest
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
Matrix4x4 m3 = m1 * m2;
|
||||
AZ_TEST_ASSERT(m3.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
AZ_TEST_ASSERT(m3.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
Matrix4x4 m4 = m1;
|
||||
m4 *= m2;
|
||||
AZ_TEST_ASSERT(m4.GetRow(0).IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(1).IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(2).IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
AZ_TEST_ASSERT(m4.GetRow(3).IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
EXPECT_THAT(m4.GetRow(0), IsClose(Vector4(150.0f, 160.0f, 170.0f, 180.0f)));
|
||||
EXPECT_THAT(m4.GetRow(1), IsClose(Vector4(358.0f, 384.0f, 410.0f, 436.0f)));
|
||||
EXPECT_THAT(m4.GetRow(2), IsClose(Vector4(566.0f, 608.0f, 650.0f, 692.0f)));
|
||||
EXPECT_THAT(m4.GetRow(3), IsClose(Vector4(774.0f, 832.0f, 890.0f, 948.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestVectorMultiplication)
|
||||
@@ -265,18 +265,148 @@ namespace UnitTest
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
AZ_TEST_ASSERT((m1 * Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(18.0f, 46.0f, 74.0f)));
|
||||
AZ_TEST_ASSERT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)).IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
|
||||
AZ_TEST_ASSERT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(38.0f, 44.0f, 50.0f)));
|
||||
AZ_TEST_ASSERT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)).IsClose(Vector3(14.0f, 38.0f, 62.0f)));
|
||||
EXPECT_THAT((m1 * Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(18.0f, 46.0f, 74.0f)));
|
||||
EXPECT_THAT((m1 * Vector4(1.0f, 2.0f, 3.0f, 4.0f)), IsClose(Vector4(30.0f, 70.0f, 110.0f, 150.0f)));
|
||||
EXPECT_THAT(m1.TransposedMultiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(38.0f, 44.0f, 50.0f)));
|
||||
EXPECT_THAT(m1.Multiply3x3(Vector3(1.0f, 2.0f, 3.0f)), IsClose(Vector3(14.0f, 38.0f, 62.0f)));
|
||||
Vector3 v1(1.0f, 2.0f, 3.0f);
|
||||
AZ_TEST_ASSERT((v1 * m1).IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
EXPECT_THAT((v1 * m1), IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
v1 *= m1;
|
||||
AZ_TEST_ASSERT(v1.IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
EXPECT_THAT(v1, IsClose(Vector3(51.0f, 58.0f, 65.0f)));
|
||||
Vector4 v2(1.0f, 2.0f, 3.0f, 4.0f);
|
||||
AZ_TEST_ASSERT((v2 * m1).IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
EXPECT_THAT((v2 * m1), IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
v2 *= m1;
|
||||
AZ_TEST_ASSERT(v2.IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
EXPECT_THAT(v2, IsClose(Vector4(90.0f, 100.0f, 110.0f, 120.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestSum)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 + m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
|
||||
|
||||
m3 = m1;
|
||||
m3 += m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(8.0f, 10.0f, 12.0f, 14.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(16.0f, 18.0f, 20.0f, 22.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(24.0f, 26.0f, 28.0f, 30.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(32.0f, 34.0f, 36.0f, 38.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestDifference)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 - m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
m3 = m1;
|
||||
m3 -= m2;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(-6.0f, -6.0f, -6.0f, -6.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScalarMultiplication)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 * 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = m1;
|
||||
m3 *= 2.0f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = 2.0f * m1;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScalarDivision)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
Matrix4x4 m2;
|
||||
m2.SetRow(0, 7.0f, 8.0f, 9.0f, 10.0f);
|
||||
m2.SetRow(1, 11.0f, 12.0f, 13.0f, 14.0f);
|
||||
m2.SetRow(2, 15.0f, 16.0f, 17.0f, 18.0f);
|
||||
m2.SetRow(3, 19.0f, 20.0f, 21.0f, 22.0f);
|
||||
|
||||
Matrix4x4 m3 = m1 / 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
m3 = m1;
|
||||
m3 /= 0.5f;
|
||||
EXPECT_THAT(m3.GetRow(0), IsClose(Vector4(2.0f, 4.0f, 6.0f, 8.0f)));
|
||||
EXPECT_THAT(m3.GetRow(1), IsClose(Vector4(10.0f, 12.0f, 14.0f, 16.0f)));
|
||||
EXPECT_THAT(m3.GetRow(2), IsClose(Vector4(18.0f, 20.0f, 22.0f, 24.0f)));
|
||||
EXPECT_THAT(m3.GetRow(3), IsClose(Vector4(26.0f, 28.0f, 30.0f, 32.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestNegation)
|
||||
{
|
||||
Matrix4x4 m1;
|
||||
m1.SetRow(0, 1.0f, 2.0f, 3.0f, 4.0f);
|
||||
m1.SetRow(1, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
m1.SetRow(2, 9.0f, 10.0f, 11.0f, 12.0f);
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
EXPECT_THAT(-(-m1), IsClose(m1));
|
||||
EXPECT_THAT(-Matrix4x4::CreateZero(), IsClose(Matrix4x4::CreateZero()));
|
||||
|
||||
Matrix4x4 m2 = -m1;
|
||||
EXPECT_THAT(m2.GetRow(0), IsClose(Vector4(-1.0f, -2.0f, -3.0f, -4.0f)));
|
||||
EXPECT_THAT(m2.GetRow(1), IsClose(Vector4(-5.0f, -6.0f, -7.0f, -8.0f)));
|
||||
EXPECT_THAT(m2.GetRow(2), IsClose(Vector4(-9.0f, -10.0f, -11.0f, -12.0f)));
|
||||
EXPECT_THAT(m2.GetRow(3), IsClose(Vector4(-13.0f, -14.0f, -15.0f, -16.0f)));
|
||||
|
||||
Matrix4x4 m3 = m1 + (-m1);
|
||||
EXPECT_THAT(m3, IsClose(Matrix4x4::CreateZero()));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestTranspose)
|
||||
@@ -368,4 +498,36 @@ namespace UnitTest
|
||||
m1.SetRow(3, 13.0f, 14.0f, 15.0f, 16.0f);
|
||||
AZ_TEST_ASSERT(m1.GetDiagonal() == Vector4(1.0f, 6.0f, 11.0f, 16.0f));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScaleAccess)
|
||||
{
|
||||
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.ExtractScale(), IsClose(Vector3(2.0f, 3.0f, 4.0f)));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScale(), IsClose(Vector3(3.0f, 4.0f, 5.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestScaleSqAccess)
|
||||
{
|
||||
Matrix4x4 m1 = Matrix4x4::CreateRotationX(DegToRad(40.0f)) * Matrix4x4::CreateScale(Vector3(2.0f, 3.0f, 4.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(4.0f, 9.0f, 16.0f)));
|
||||
m1.ExtractScale();
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3::CreateOne()));
|
||||
m1.MultiplyByScale(Vector3(3.0f, 4.0f, 5.0f));
|
||||
EXPECT_THAT(m1.RetrieveScaleSq(), IsClose(Vector3(9.0f, 16.0f, 25.0f)));
|
||||
}
|
||||
|
||||
TEST(MATH_Matrix4x4, TestReciprocalScaled)
|
||||
{
|
||||
Matrix4x4 orthogonalMatrix = Matrix4x4::CreateRotationX(DegToRad(40.0f));
|
||||
EXPECT_THAT(orthogonalMatrix.GetReciprocalScaled(), IsClose(orthogonalMatrix));
|
||||
const AZ::Vector3 scale(2.8f, 0.7f, 1.3f);
|
||||
AZ::Matrix4x4 scaledMatrix = orthogonalMatrix;
|
||||
scaledMatrix.MultiplyByScale(scale);
|
||||
AZ::Matrix4x4 reciprocalScaledMatrix = orthogonalMatrix;
|
||||
reciprocalScaledMatrix.MultiplyByScale(scale.GetReciprocal());
|
||||
EXPECT_THAT(scaledMatrix.GetReciprocalScaled(), IsClose(reciprocalScaledMatrix));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(42, value);
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_PointerInstance_ValueLoadedCorrectly)
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_ToPointerInstance_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -126,6 +126,51 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(42, value);
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_ToNullPointer_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json;
|
||||
json.Set(42);
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, ptrValue);
|
||||
EXPECT_EQ(42, *ptrValue);
|
||||
|
||||
azfree(ptrValue, AZ::SystemAllocator, sizeof(int), alignof(int));
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_DefaultToNullPointer_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json(rapidjson::kObjectType);
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_NE(nullptr, ptrValue);
|
||||
|
||||
azfree(ptrValue, AZ::SystemAllocator, sizeof(int), alignof(int));
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueLoading_NullDeletesObject_ValueLoadedCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
rapidjson::Value json(rapidjson::kNullType);
|
||||
int* ptrValue = reinterpret_cast<int*>(azmalloc(sizeof(int), alignof(int), AZ::SystemAllocator));
|
||||
|
||||
ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid<int>(), json, *m_jsonDeserializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
ASSERT_EQ(nullptr, ptrValue);
|
||||
}
|
||||
|
||||
//
|
||||
// ContinueStoring
|
||||
//
|
||||
@@ -156,6 +201,64 @@ namespace JsonSerializationTests
|
||||
Expect_DocStrEq("42");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToFullDefaultedInstance_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int value = 42;
|
||||
int* ptrValue = &value;
|
||||
int value2 = 42;
|
||||
int* defaultPtrValue = &value2;
|
||||
|
||||
ResultCode result =
|
||||
ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("{}");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptr_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
|
||||
ResultCode result = ContinueStoring(
|
||||
*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid<int>(), *m_jsonSerializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptrWithValueDefault_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
int value2 = 42;
|
||||
int* defaultPtrValue = &value2;
|
||||
|
||||
ResultCode result =
|
||||
ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_StorePointerToNullptrWithNullPtrDefault_NullPtrIsStored)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
int* ptrValue = nullptr;
|
||||
int* defaultPtrValue = nullptr;
|
||||
|
||||
ResultCode result =
|
||||
ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid<int>(), *m_jsonSerializationContext, Flags::ResolvePointer);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
Expect_DocStrEq("null");
|
||||
}
|
||||
|
||||
TEST_F(BaseJsonSerializerTests, ContinueStoring_ReplaceDefault_ValueStoredCorrectly)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -32,11 +32,6 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<AZ::JsonSmartPointerSerializer>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<SmartPointer>();
|
||||
}
|
||||
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
{
|
||||
context->RegisterGenericType<SmartPointer>();
|
||||
@@ -51,6 +46,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<SimpleClass>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew SimpleClass());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
@@ -106,21 +108,6 @@ namespace JsonSerializationTests
|
||||
}
|
||||
};
|
||||
|
||||
template<template<typename...> class T>
|
||||
class SmartPointerSimpleClassWithInstanceTestDescription :
|
||||
public SmartPointerSimpleClassTestDescription<T>
|
||||
{
|
||||
public:
|
||||
using SmartPointer = typename SmartPointerSimpleClassTestDescription<T>::SmartPointer;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew SimpleClass());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template<template<typename...> class T>
|
||||
class SmartPointerSimpleDerivedClassTestDescription :
|
||||
public SmartPointerBaseTestDescription<T<BaseClass>>
|
||||
@@ -129,6 +116,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<BaseClass>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew BaseClass());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto* instance = aznew SimpleInheritence();
|
||||
@@ -272,6 +266,13 @@ namespace JsonSerializationTests
|
||||
using SmartPointer = T<BaseClass2>;
|
||||
using Base = SmartPointerBaseTestDescription<SmartPointer>;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateDefaultInstance() override
|
||||
{
|
||||
auto result = AZStd::make_shared<SmartPointer>();
|
||||
*result = SmartPointer(aznew BaseClass2());
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> CreateFullySetInstance() override
|
||||
{
|
||||
auto* instance = aznew MultipleInheritence();
|
||||
@@ -424,9 +425,6 @@ namespace JsonSerializationTests
|
||||
SmartPointerSimpleClassTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleClassTestDescription<AZStd::shared_ptr>,
|
||||
SmartPointerSimpleClassTestDescription<AZStd::intrusive_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::shared_ptr>,
|
||||
SmartPointerSimpleClassWithInstanceTestDescription<AZStd::intrusive_ptr>,
|
||||
// Simple derived class, include single inheritance.
|
||||
SmartPointerSimpleDerivedClassTestDescription<AZStd::unique_ptr>,
|
||||
SmartPointerSimpleDerivedClassTestDescription<AZStd::shared_ptr>,
|
||||
@@ -551,6 +549,37 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(nullptr, *instance);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_DefaultInstanceToNullptr_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
AZStd::shared_ptr<SmartPointer> compare = m_description.CreateDefaultInstance();
|
||||
m_jsonDocument->SetObject();
|
||||
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Load(&instance, azrtti_typeid<SmartPointer>(), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
EXPECT_NE(nullptr, instance);
|
||||
EXPECT_TRUE(m_description.AreEqual(instance, *compare));
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_DefaultObjectDoesNotUpdateInstance_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateFullySetInstance();
|
||||
AZStd::shared_ptr<SmartPointer> compare = m_description.CreateFullySetInstance();
|
||||
m_jsonDocument->SetObject();
|
||||
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Load(instance.get(), azrtti_typeid<SmartPointer>(), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
EXPECT_TRUE(m_description.AreEqual(*instance, *compare));
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Load_InstanceBeingReplacedWithDifferentType_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
@@ -720,13 +749,66 @@ namespace JsonSerializationTests
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateFullySetInstance();
|
||||
SmartPointer nullPtr;
|
||||
JSR::ResultCode result = m_serializer.Store(*m_jsonDocument, instance.get(), &nullPtr,
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, instance.get(), &defaultInstance,
|
||||
azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::Success, result.GetOutcome());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValuePointerIsNullPtr_ReturnsSuccessAndStoresNull)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
AZStd::shared_ptr<SmartPointer> defaultInstance = m_description.CreateFullySetInstance();
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, &instance, defaultInstance.get(), azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::Success, result.GetOutcome());
|
||||
EXPECT_TRUE(m_jsonDocument->IsNull());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueAndDefaultPointersAreNullPtr_ReturnsSuccessAndStoresNull)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
SmartPointer instance;
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Store(*m_jsonDocument, &instance, &defaultInstance, azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_TRUE(m_jsonDocument->IsNull());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueAndDefaultPointersAreBothDefault_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateDefaultInstance();
|
||||
AZStd::shared_ptr<SmartPointer> defaultInstance = m_description.CreateDefaultInstance();
|
||||
JSR::ResultCode result =
|
||||
m_serializer.Store(*m_jsonDocument, instance.get(), defaultInstance.get(), azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
Expect_ExplicitDefault(*m_jsonDocument);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ValueHasDefaultValuesAndDefaultHasNullPointer_ReturnsSuccess)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
AZStd::shared_ptr<SmartPointer> instance = m_description.CreateDefaultInstance();
|
||||
SmartPointer defaultInstance;
|
||||
JSR::ResultCode result = m_serializer.Store(
|
||||
*m_jsonDocument, instance.get(), &defaultInstance, azrtti_typeid<SmartPointer>(), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(JSR::Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
Expect_ExplicitDefault(*m_jsonDocument);
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_DefaultPointerIsOtherClass_CompletesButDoesNotReturnDefaults)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
@@ -749,7 +831,7 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(JSR::Processing::Completed, result.GetProcessing());
|
||||
}
|
||||
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_SaveAnClassThatIsNotReflected_ReturnsUnknown)
|
||||
TEST_F(JsonSmartPointerSerializerTests, Store_ClassThatIsNotReflected_ReturnsUnknown)
|
||||
{
|
||||
namespace JSR = AZ::JsonSerializationResult;
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
class AtomActiveInterface
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(AtomActiveInterface, "{4BB59C86-0848-485D-AB28-700540470B2B}");
|
||||
|
||||
AtomActiveInterface() = default;
|
||||
virtual ~AtomActiveInterface() = default;
|
||||
};
|
||||
} // namespace AzFramework
|
||||
@@ -137,7 +137,7 @@ namespace AzFramework::ProjectManager
|
||||
}
|
||||
AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python";
|
||||
pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL;
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRId64, pythonPath.Native().c_str(),
|
||||
auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(),
|
||||
debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId());
|
||||
|
||||
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Scene::UnsetSubsystem(const T& system)
|
||||
bool Scene::UnsetSubsystem([[maybe_unused]] const T& system)
|
||||
{
|
||||
const AZ::TypeId& targetType = azrtti_typeid<T>();
|
||||
const size_t systemKeysCount = m_systemKeys.size();
|
||||
|
||||
@@ -12,14 +12,150 @@
|
||||
|
||||
#include "CameraInput.h"
|
||||
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Math/MathUtils.h>
|
||||
#include <AzCore/Math/Plane.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void CameraSystem::HandleEvents(const InputEvent& event)
|
||||
AZ_CVAR(
|
||||
float, ed_cameraSystemDefaultPlaneHeight, 34.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"The default height of the ground plane to do intersection tests against when orbiting");
|
||||
AZ_CVAR(float, ed_cameraSystemBoostMultiplier, 3.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSpeed, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemDefaultOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 100.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemPanSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertX, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(bool, ed_cameraSystemPanInvertY, true, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateForwardKey, "keyboard_key_alphanumeric_W", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateBackwardKey, "keyboard_key_alphanumeric_S", nullptr, AZ::ConsoleFunctorFlags::Null,
|
||||
"");
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateLeftKey, "keyboard_key_alphanumeric_A", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateRightKey, "keyboard_key_alphanumeric_D", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemTranslateUpKey, "keyboard_key_alphanumeric_E", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateDownKey, "keyboard_key_alphanumeric_Q", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(
|
||||
AZ::CVarFixedString, ed_cameraSystemTranslateBoostKey, "keyboard_key_modifier_shift_l", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitKey, "keyboard_key_modifier_alt_l", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreeLookButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemFreePanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitLookButton, "mouse_button_left", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitDollyButton, "mouse_button_right", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(AZ::CVarFixedString, ed_cameraSystemOrbitPanButton, "mouse_button_middle", nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
|
||||
static InputChannelId CameraTranslateForwardId;
|
||||
static InputChannelId CameraTranslateBackwardId;
|
||||
static InputChannelId CameraTranslateLeftId;
|
||||
static InputChannelId CameraTranslateRightId;
|
||||
static InputChannelId CameraTranslateDownId;
|
||||
static InputChannelId CameraTranslateUpId;
|
||||
static InputChannelId CameraTranslateBoostId;
|
||||
static InputChannelId CameraOrbitId;
|
||||
|
||||
// externed elsewhere
|
||||
InputChannelId CameraFreeLookButton;
|
||||
InputChannelId CameraFreePanButton;
|
||||
InputChannelId CameraOrbitLookButton;
|
||||
InputChannelId CameraOrbitDollyButton;
|
||||
InputChannelId CameraOrbitPanButton;
|
||||
|
||||
void ReloadCameraKeyBindings()
|
||||
{
|
||||
const AZ::CVarFixedString& forward = ed_cameraSystemTranslateForwardKey;
|
||||
CameraTranslateForwardId = InputChannelId(forward.c_str());
|
||||
const AZ::CVarFixedString& backward = ed_cameraSystemTranslateBackwardKey;
|
||||
CameraTranslateBackwardId = InputChannelId(backward.c_str());
|
||||
const AZ::CVarFixedString& left = ed_cameraSystemTranslateLeftKey;
|
||||
CameraTranslateLeftId = InputChannelId(left.c_str());
|
||||
const AZ::CVarFixedString& right = ed_cameraSystemTranslateRightKey;
|
||||
CameraTranslateRightId = InputChannelId(right.c_str());
|
||||
const AZ::CVarFixedString& down = ed_cameraSystemTranslateDownKey;
|
||||
CameraTranslateDownId = InputChannelId(down.c_str());
|
||||
const AZ::CVarFixedString& up = ed_cameraSystemTranslateUpKey;
|
||||
CameraTranslateUpId = InputChannelId(up.c_str());
|
||||
const AZ::CVarFixedString& boost = ed_cameraSystemTranslateBoostKey;
|
||||
CameraTranslateBoostId = InputChannelId(boost.c_str());
|
||||
const AZ::CVarFixedString& orbit = ed_cameraSystemOrbitKey;
|
||||
CameraOrbitId = InputChannelId(orbit.c_str());
|
||||
const AZ::CVarFixedString& freeLook = ed_cameraSystemFreeLookButton;
|
||||
CameraFreeLookButton = InputChannelId(freeLook.c_str());
|
||||
const AZ::CVarFixedString& freePan = ed_cameraSystemFreePanButton;
|
||||
CameraFreePanButton = InputChannelId(freePan.c_str());
|
||||
const AZ::CVarFixedString& orbitLook = ed_cameraSystemOrbitLookButton;
|
||||
CameraOrbitLookButton = InputChannelId(orbitLook.c_str());
|
||||
const AZ::CVarFixedString& orbitDolly = ed_cameraSystemOrbitDollyButton;
|
||||
CameraOrbitDollyButton = InputChannelId(orbitDolly.c_str());
|
||||
const AZ::CVarFixedString& orbitPan = ed_cameraSystemOrbitPanButton;
|
||||
CameraOrbitPanButton = InputChannelId(orbitPan.c_str());
|
||||
}
|
||||
|
||||
static void ReloadCameraKeyBindingsConsole(const AZ::ConsoleCommandContainer&)
|
||||
{
|
||||
ReloadCameraKeyBindings();
|
||||
}
|
||||
|
||||
AZ_CONSOLEFREEFUNC(ReloadCameraKeyBindingsConsole, AZ::ConsoleFunctorFlags::Null, "Reload keybindings for the modern camera system");
|
||||
|
||||
// Based on paper by David Eberly - https://www.geometrictools.com/Documentation/EulerAngles.pdf
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation)
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
|
||||
// 2.4 Factor as RzRyRx
|
||||
if (orientation.GetElement(2, 0) < 1.0f)
|
||||
{
|
||||
if (orientation.GetElement(2, 0) > -1.0f)
|
||||
{
|
||||
x = std::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2));
|
||||
y = std::asin(-orientation.GetElement(2, 0));
|
||||
z = std::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 0.0f;
|
||||
y = AZ::Constants::Pi * 0.5f;
|
||||
z = -std::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 0.0f;
|
||||
y = -AZ::Constants::Pi * 0.5f;
|
||||
z = std::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1));
|
||||
}
|
||||
|
||||
return {x, y, z};
|
||||
}
|
||||
|
||||
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform)
|
||||
{
|
||||
const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromTransform(transform));
|
||||
|
||||
camera.m_lookAt = transform.GetTranslation();
|
||||
camera.m_pitch = eulerAngles.GetX();
|
||||
camera.m_yaw = eulerAngles.GetZ();
|
||||
}
|
||||
|
||||
bool CameraSystem::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
if (const auto& cursor_motion = AZStd::get_if<CursorMotionEvent>(&event))
|
||||
{
|
||||
@@ -30,10 +166,10 @@ namespace AzFramework
|
||||
m_scrollDelta = scroll->m_delta;
|
||||
}
|
||||
|
||||
m_cameras.HandleEvents(event);
|
||||
return m_cameras.HandleEvents(event);
|
||||
}
|
||||
|
||||
Camera CameraSystem::StepCamera(const Camera& targetCamera, float deltaTime)
|
||||
Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime)
|
||||
{
|
||||
const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value()
|
||||
? m_currentCursorPosition.value() - m_lastCursorPosition.value()
|
||||
@@ -51,36 +187,41 @@ namespace AzFramework
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> camera_input)
|
||||
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
|
||||
{
|
||||
m_idleCameraInputs.push_back(AZStd::move(camera_input));
|
||||
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
|
||||
}
|
||||
|
||||
void Cameras::HandleEvents(const InputEvent& event)
|
||||
bool Cameras::HandleEvents(const InputEvent& event)
|
||||
{
|
||||
for (auto& camera_input : m_activeCameraInputs)
|
||||
bool handling = false;
|
||||
for (auto& cameraInput : m_activeCameraInputs)
|
||||
{
|
||||
camera_input->HandleEvents(event);
|
||||
cameraInput->HandleEvents(event);
|
||||
handling = !cameraInput->Idle() || handling;
|
||||
}
|
||||
|
||||
for (auto& camera_input : m_idleCameraInputs)
|
||||
for (auto& cameraInput : m_idleCameraInputs)
|
||||
{
|
||||
camera_input->HandleEvents(event);
|
||||
cameraInput->HandleEvents(event);
|
||||
}
|
||||
|
||||
return handling;
|
||||
}
|
||||
|
||||
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, const float deltaTime)
|
||||
Camera Cameras::StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
|
||||
{
|
||||
for (int i = 0; i < m_idleCameraInputs.size();)
|
||||
{
|
||||
auto& camera_input = m_idleCameraInputs[i];
|
||||
const bool can_begin = camera_input->Beginning() &&
|
||||
auto& cameraInput = m_idleCameraInputs[i];
|
||||
const bool canBegin = cameraInput->Beginning() &&
|
||||
std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(),
|
||||
[](const auto& input) { return !input->Exclusive(); }) &&
|
||||
(!camera_input->Exclusive() || (camera_input->Exclusive() && m_activeCameraInputs.empty()));
|
||||
if (can_begin)
|
||||
(!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty()));
|
||||
|
||||
if (canBegin)
|
||||
{
|
||||
m_activeCameraInputs.push_back(camera_input);
|
||||
m_activeCameraInputs.push_back(cameraInput);
|
||||
using AZStd::swap;
|
||||
swap(m_idleCameraInputs[i], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
|
||||
m_idleCameraInputs.pop_back();
|
||||
@@ -93,25 +234,25 @@ namespace AzFramework
|
||||
|
||||
// accumulate
|
||||
Camera nextCamera = targetCamera;
|
||||
for (auto& camera_input : m_activeCameraInputs)
|
||||
for (auto& cameraInput : m_activeCameraInputs)
|
||||
{
|
||||
nextCamera = camera_input->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
nextCamera = cameraInput->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_activeCameraInputs.size();)
|
||||
{
|
||||
auto& camera_input = m_activeCameraInputs[i];
|
||||
if (camera_input->Ending())
|
||||
auto& cameraInput = m_activeCameraInputs[i];
|
||||
if (cameraInput->Ending())
|
||||
{
|
||||
camera_input->ClearActivation();
|
||||
m_idleCameraInputs.push_back(camera_input);
|
||||
cameraInput->ClearActivation();
|
||||
m_idleCameraInputs.push_back(cameraInput);
|
||||
using AZStd::swap;
|
||||
swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
|
||||
m_activeCameraInputs.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
camera_input->ContinueActivation();
|
||||
cameraInput->ContinueActivation();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -134,7 +275,7 @@ namespace AzFramework
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == m_channelId)
|
||||
if (input->m_channelId == m_rotateChannelId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
@@ -154,14 +295,14 @@ namespace AzFramework
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
nextCamera.m_pitch += float(cursorDelta.m_y) * m_props.m_rotateSpeed;
|
||||
nextCamera.m_yaw += float(cursorDelta.m_x) * m_props.m_rotateSpeed;
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed;
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed;
|
||||
|
||||
auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoOverPi, AZ::Constants::TwoOverPi); };
|
||||
const auto clampRotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
|
||||
|
||||
nextCamera.m_yaw = clamp_rotation(nextCamera.m_yaw);
|
||||
nextCamera.m_yaw = clampRotation(nextCamera.m_yaw);
|
||||
// clamp pitch to be +-90 degrees
|
||||
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::Pi * 0.5f, AZ::Constants::Pi * 0.5f);
|
||||
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -170,7 +311,7 @@ namespace AzFramework
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceMouse::Button::Middle)
|
||||
if (input->m_channelId == m_panChannelId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
@@ -190,51 +331,50 @@ namespace AzFramework
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto pan_axes = m_panAxesFn(nextCamera);
|
||||
const auto panAxes = m_panAxesFn(nextCamera);
|
||||
|
||||
const auto delta_pan_x = float(cursorDelta.m_x) * pan_axes.m_horizontalAxis * m_props.m_panSpeed;
|
||||
const auto delta_pan_y = float(cursorDelta.m_y) * pan_axes.m_verticalAxis * m_props.m_panSpeed;
|
||||
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * ed_cameraSystemPanSpeed;
|
||||
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * ed_cameraSystemPanSpeed;
|
||||
|
||||
const auto inv = [](const bool invert) {
|
||||
constexpr float Dir[] = {1.0f, -1.0f};
|
||||
return Dir[static_cast<int>(invert)];
|
||||
};
|
||||
|
||||
nextCamera.m_lookAt += delta_pan_x * inv(m_props.m_panInvertX);
|
||||
nextCamera.m_lookAt += delta_pan_y * -inv(m_props.m_panInvertY);
|
||||
nextCamera.m_lookAt += deltaPanX * inv(ed_cameraSystemPanInvertX);
|
||||
nextCamera.m_lookAt += deltaPanY * -inv(ed_cameraSystemPanInvertY);
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
TranslateCameraInput::TranslationType TranslateCameraInput::translationFromKey(InputChannelId channelId)
|
||||
{
|
||||
// note: remove hard-coded InputDevice keys
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericW)
|
||||
if (channelId == CameraTranslateForwardId)
|
||||
{
|
||||
return TranslationType::Forward;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericS)
|
||||
if (channelId == CameraTranslateBackwardId)
|
||||
{
|
||||
return TranslationType::Backward;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericA)
|
||||
if (channelId == CameraTranslateLeftId)
|
||||
{
|
||||
return TranslationType::Left;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericD)
|
||||
if (channelId == CameraTranslateRightId)
|
||||
{
|
||||
return TranslationType::Right;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericQ)
|
||||
if (channelId == CameraTranslateDownId)
|
||||
{
|
||||
return TranslationType::Down;
|
||||
}
|
||||
|
||||
if (channelId == InputDeviceKeyboard::Key::AlphanumericE)
|
||||
if (channelId == CameraTranslateUpId)
|
||||
{
|
||||
return TranslationType::Up;
|
||||
}
|
||||
@@ -259,19 +399,19 @@ namespace AzFramework
|
||||
BeginActivation();
|
||||
}
|
||||
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
if (input->m_channelId == CameraTranslateBoostId)
|
||||
{
|
||||
m_boost = true;
|
||||
}
|
||||
}
|
||||
else if (input->m_state == InputChannel::State::Ended)
|
||||
{
|
||||
m_translation ^= translationFromKey(input->m_channelId);
|
||||
m_translation &= ~(translationFromKey(input->m_channelId));
|
||||
if (m_translation == TranslationType::Nil)
|
||||
{
|
||||
EndActivation();
|
||||
}
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierShiftL)
|
||||
if (input->m_channelId == CameraTranslateBoostId)
|
||||
{
|
||||
m_boost = false;
|
||||
}
|
||||
@@ -285,13 +425,13 @@ namespace AzFramework
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto translation_basis = m_translationAxesFn(nextCamera);
|
||||
const auto axisX = translation_basis.GetBasisX();
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
const auto axisZ = translation_basis.GetBasisZ();
|
||||
const auto translationBasis = m_translationAxesFn(nextCamera);
|
||||
const auto axisX = translationBasis.GetBasisX();
|
||||
const auto axisY = translationBasis.GetBasisY();
|
||||
const auto axisZ = translationBasis.GetBasisZ();
|
||||
|
||||
const float speed = [boost = m_boost, props = m_props]() {
|
||||
return props.m_translateSpeed * (boost ? props.m_boostMultiplier : 1.0f);
|
||||
const float speed = [boost = m_boost]() {
|
||||
return ed_cameraSystemTranslateSpeed * (boost ? ed_cameraSystemBoostMultiplier : 1.0f);
|
||||
}();
|
||||
|
||||
if ((m_translation & TranslationType::Forward) == TranslationType::Forward)
|
||||
@@ -342,12 +482,8 @@ namespace AzFramework
|
||||
{
|
||||
if (const auto* input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierAltL)
|
||||
if (input->m_channelId == CameraOrbitId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Updated)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
BeginActivation();
|
||||
@@ -358,7 +494,7 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
|
||||
if (Active())
|
||||
{
|
||||
m_orbitCameras.HandleEvents(event);
|
||||
@@ -366,29 +502,29 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
Camera OrbitCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, float deltaTime)
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
if (Beginning())
|
||||
{
|
||||
float hit_distance = 0.0f;
|
||||
if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateZero())
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY() * m_props.m_maxOrbitDistance, hit_distance))
|
||||
if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight))
|
||||
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance))
|
||||
{
|
||||
hit_distance = AZStd::min<float>(hit_distance, ed_cameraSystemMaxOrbitDistance);
|
||||
nextCamera.m_lookDist = -hit_distance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextCamera.m_lookDist = -m_props.m_defaultOrbitDistance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * m_props.m_defaultOrbitDistance;
|
||||
nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance;
|
||||
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance;
|
||||
}
|
||||
}
|
||||
|
||||
if (Active())
|
||||
{
|
||||
// todo: need to return nested cameras to idle state when ending
|
||||
nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
}
|
||||
|
||||
@@ -413,10 +549,10 @@ namespace AzFramework
|
||||
|
||||
Camera OrbitDollyScrollCameraInput::StepCamera(
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
|
||||
[[maybe_unused]] float deltaTime)
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_props.m_dollySpeed, 0.0f);
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * ed_cameraSystemOrbitDollyScrollSpeed, 0.0f);
|
||||
EndActivation();
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -425,7 +561,7 @@ namespace AzFramework
|
||||
{
|
||||
if (const auto& input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == InputDeviceMouse::Button::Right)
|
||||
if (input->m_channelId == m_dollyChannelId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
@@ -444,7 +580,7 @@ namespace AzFramework
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_props.m_dollySpeed, 0.0f);
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * ed_cameraSystemOrbitDollyCursorSpeed, 0.0f);
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
@@ -457,7 +593,7 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
Camera ScrollTranslationCameraInput::StepCamera(
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, float scrollDelta,
|
||||
const Camera& targetCamera, [[maybe_unused]] const ScreenVector& cursorDelta, const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
@@ -465,38 +601,39 @@ namespace AzFramework
|
||||
const auto translation_basis = LookTranslation(nextCamera);
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * m_props.m_translateSpeed;
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * ed_cameraSystemScrollTranslateSpeed;
|
||||
|
||||
EndActivation();
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, const float deltaTime)
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime)
|
||||
{
|
||||
const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); };
|
||||
|
||||
// keep yaw in 0 - 360 range
|
||||
float target_yaw = clamp_rotation(targetCamera.m_yaw);
|
||||
const float current_yaw = clamp_rotation(currentCamera.m_yaw);
|
||||
float targetYaw = clamp_rotation(targetCamera.m_yaw);
|
||||
const float currentYaw = clamp_rotation(currentCamera.m_yaw);
|
||||
|
||||
auto sign = [](const float value) { return static_cast<float>((0.0f < value) - (value < 0.0f)); };
|
||||
// return the sign of the float input (-1, 0, 1)
|
||||
const auto sign = [](const float value) { return aznumeric_cast<float>((0.0f < value) - (value < 0.0f)); };
|
||||
|
||||
// ensure smooth transition when moving across 0 - 360 boundary
|
||||
const float yaw_delta = target_yaw - current_yaw;
|
||||
if (std::abs(yaw_delta) >= AZ::Constants::Pi)
|
||||
const float yawDelta = targetYaw - currentYaw;
|
||||
if (std::abs(yawDelta) >= AZ::Constants::Pi)
|
||||
{
|
||||
target_yaw -= AZ::Constants::TwoPi * sign(yaw_delta);
|
||||
targetYaw -= AZ::Constants::TwoPi * sign(yawDelta);
|
||||
}
|
||||
|
||||
Camera camera;
|
||||
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
|
||||
// note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent
|
||||
// article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
|
||||
const float lookRate = std::exp2(props.m_lookSmoothness);
|
||||
const float lookRate = std::exp2(ed_cameraSystemLookSmoothness);
|
||||
const float lookT = std::exp2(-lookRate * deltaTime);
|
||||
camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT);
|
||||
camera.m_yaw = AZ::Lerp(target_yaw, current_yaw, lookT);
|
||||
const float moveRate = std::exp2(props.m_moveSmoothness);
|
||||
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT);
|
||||
const float moveRate = std::exp2(ed_cameraSystemTranslateSmoothness);
|
||||
const float moveT = std::exp2(-moveRate * deltaTime);
|
||||
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
|
||||
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT);
|
||||
@@ -508,20 +645,24 @@ namespace AzFramework
|
||||
const auto& inputChannelId = inputChannel.GetInputChannelId();
|
||||
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
|
||||
|
||||
if (inputChannelId == InputDeviceMouse::SystemCursorPosition)
|
||||
const bool wasMouseButton =
|
||||
AZStd::any_of(InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), [inputChannelId](const auto& button) {
|
||||
return button == inputChannelId;
|
||||
});
|
||||
|
||||
if (inputChannelId == InputDeviceMouse::Movement::X || inputChannelId == InputDeviceMouse::Movement::Y)
|
||||
{
|
||||
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
|
||||
InputSystemCursorRequestBus::EventResult(
|
||||
systemCursorPositionNormalized, inputDeviceId, &InputSystemCursorRequestBus::Events::GetSystemCursorPositionNormalized);
|
||||
const auto* position = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
|
||||
AZ_Assert(position, "Expected PositionData2D but found nullptr");
|
||||
|
||||
return CursorMotionEvent{ScreenPoint(
|
||||
systemCursorPositionNormalized.GetX() * windowSize.m_width, systemCursorPositionNormalized.GetY() * windowSize.m_height)};
|
||||
position->m_normalizedPosition.GetX() * windowSize.m_width, position->m_normalizedPosition.GetY() * windowSize.m_height)};
|
||||
}
|
||||
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
||||
{
|
||||
return ScrollEvent{inputChannel.GetValue()};
|
||||
}
|
||||
else if (InputDeviceMouse::IsMouseDevice(inputDeviceId) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
|
||||
else if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
|
||||
{
|
||||
return DiscreteInputEvent{inputChannelId, inputChannel.GetState()};
|
||||
}
|
||||
|
||||
@@ -17,13 +17,16 @@
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzFramework/Input/Channels/InputChannel.h>
|
||||
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
||||
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
||||
#include <AzFramework/Viewport/ScreenGeometry.h>
|
||||
#include <AzFramework/Viewport/ViewportId.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct WindowSize;
|
||||
//! Update camera key bindings that can be overridden with AZ console vars (invoke from console to update)
|
||||
void ReloadCameraKeyBindings();
|
||||
|
||||
//! Return Euler angles (pitch, roll, yaw) for the incoming orientation.
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
|
||||
|
||||
struct Camera
|
||||
{
|
||||
@@ -51,8 +54,8 @@ namespace AzFramework
|
||||
|
||||
inline AZ::Transform Camera::Transform() const
|
||||
{
|
||||
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationX(m_pitch) *
|
||||
AZ::Transform::CreateRotationZ(m_yaw) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisZ(m_lookDist));
|
||||
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationZ(m_yaw) *
|
||||
AZ::Transform::CreateRotationX(m_pitch) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(m_lookDist));
|
||||
}
|
||||
|
||||
inline AZ::Matrix3x3 Camera::Rotation() const
|
||||
@@ -65,6 +68,8 @@ namespace AzFramework
|
||||
return Transform().GetTranslation();
|
||||
}
|
||||
|
||||
void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform);
|
||||
|
||||
struct CursorMotionEvent
|
||||
{
|
||||
ScreenPoint m_position;
|
||||
@@ -159,19 +164,13 @@ namespace AzFramework
|
||||
Activation m_activation = Activation::Idle;
|
||||
};
|
||||
|
||||
struct SmoothProps
|
||||
{
|
||||
float m_lookSmoothness = 5.0f;
|
||||
float m_moveSmoothness = 5.0f;
|
||||
};
|
||||
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const SmoothProps& props, float deltaTime);
|
||||
Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, float deltaTime);
|
||||
|
||||
class Cameras
|
||||
{
|
||||
public:
|
||||
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
|
||||
void HandleEvents(const InputEvent& event);
|
||||
bool HandleEvents(const InputEvent& event);
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime);
|
||||
void Reset();
|
||||
|
||||
@@ -183,7 +182,7 @@ namespace AzFramework
|
||||
class CameraSystem
|
||||
{
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event);
|
||||
bool HandleEvents(const InputEvent& event);
|
||||
Camera StepCamera(const Camera& targetCamera, float deltaTime);
|
||||
|
||||
Cameras m_cameras;
|
||||
@@ -197,19 +196,16 @@ namespace AzFramework
|
||||
class RotateCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit RotateCameraInput(const InputChannelId channelId)
|
||||
: m_channelId(channelId)
|
||||
explicit RotateCameraInput(const InputChannelId rotateChannelId)
|
||||
: m_rotateChannelId(rotateChannelId)
|
||||
{
|
||||
}
|
||||
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
InputChannelId m_channelId;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_rotateSpeed = 0.005f;
|
||||
} m_props;
|
||||
private:
|
||||
InputChannelId m_rotateChannelId;
|
||||
};
|
||||
|
||||
struct PanAxes
|
||||
@@ -242,22 +238,17 @@ namespace AzFramework
|
||||
class PanCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit PanCameraInput(PanAxesFn panAxesFn)
|
||||
PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn)
|
||||
: m_panAxesFn(AZStd::move(panAxesFn))
|
||||
, m_panChannelId(panChannelId)
|
||||
{
|
||||
}
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_panSpeed = 0.01f;
|
||||
bool m_panInvertX = true;
|
||||
bool m_panInvertY = true;
|
||||
} m_props;
|
||||
|
||||
private:
|
||||
PanAxesFn m_panAxesFn;
|
||||
InputChannelId m_panChannelId;
|
||||
};
|
||||
|
||||
using TranslationAxesFn = AZStd::function<AZ::Matrix3x3(const Camera& camera)>;
|
||||
@@ -298,17 +289,11 @@ namespace AzFramework
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
void ResetImpl() override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_translateSpeed = 10.0f;
|
||||
float m_boostMultiplier = 3.0f;
|
||||
} m_props;
|
||||
|
||||
private:
|
||||
enum class TranslationType
|
||||
{
|
||||
// clang-format off
|
||||
Nil = 0,
|
||||
Nil = 0,
|
||||
Forward = 1 << 0,
|
||||
Backward = 1 << 1,
|
||||
Left = 1 << 2,
|
||||
@@ -354,6 +339,11 @@ namespace AzFramework
|
||||
return lhs;
|
||||
}
|
||||
|
||||
friend TranslationType operator~(const TranslationType lhs)
|
||||
{
|
||||
return static_cast<TranslationType>(~static_cast<std::underlying_type_t<TranslationType>>(lhs));
|
||||
}
|
||||
|
||||
static TranslationType translationFromKey(InputChannelId channelId);
|
||||
|
||||
TranslationType m_translation = TranslationType::Nil;
|
||||
@@ -366,23 +356,19 @@ namespace AzFramework
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_dollySpeed = 0.2f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
class OrbitDollyCursorMoveCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId)
|
||||
: m_dollyChannelId(dollyChannelId) {}
|
||||
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_dollySpeed = 0.1f;
|
||||
} m_props;
|
||||
private:
|
||||
InputChannelId m_dollyChannelId;
|
||||
};
|
||||
|
||||
class ScrollTranslationCameraInput : public CameraInput
|
||||
@@ -390,11 +376,6 @@ namespace AzFramework
|
||||
public:
|
||||
void HandleEvents(const InputEvent& event) override;
|
||||
Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_translateSpeed = 0.2f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
class OrbitCameraInput : public CameraInput
|
||||
@@ -408,13 +389,10 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
Cameras m_orbitCameras;
|
||||
|
||||
struct Props
|
||||
{
|
||||
float m_defaultOrbitDistance = 15.0f;
|
||||
float m_maxOrbitDistance = 100.0f;
|
||||
} m_props;
|
||||
};
|
||||
|
||||
struct WindowSize;
|
||||
|
||||
//! Map from a generic InputChannel event to a camera specific InputEvent.
|
||||
InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize);
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -14,7 +14,6 @@ set(FILES
|
||||
AzFrameworkModule.h
|
||||
AzFrameworkModule.cpp
|
||||
API/ApplicationAPI.h
|
||||
API/AtomActiveInterface.h
|
||||
Application/Application.cpp
|
||||
Application/Application.h
|
||||
Archive/Archive.cpp
|
||||
|
||||
+4
-3
@@ -38,8 +38,9 @@ namespace AzManipulatorTestFramework
|
||||
void SetGridSize(float size) override;
|
||||
void SetAngularStep(float step) override;
|
||||
int GetViewportId() const override;
|
||||
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const QPoint& screenPosition, float depth) override;
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(const QPoint& screenPosition) override;
|
||||
AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) override;
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportScreenToWorldRay(
|
||||
const AzFramework::ScreenPoint& screenPosition) override;
|
||||
private:
|
||||
// ViewportInteractionRequestBus ...
|
||||
bool GridSnappingEnabled();
|
||||
@@ -47,7 +48,7 @@ namespace AzManipulatorTestFramework
|
||||
bool ShowGrid();
|
||||
bool AngleSnappingEnabled();
|
||||
float AngleStep();
|
||||
QPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition);
|
||||
AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition);
|
||||
private:
|
||||
AZStd::unique_ptr<NullDebugDisplayRequests> m_nullDebugDisplayRequests;
|
||||
const int m_viewportId = 1234; // Arbitrary viewport id for manipulator tests
|
||||
|
||||
@@ -66,10 +66,9 @@ namespace AzManipulatorTestFramework
|
||||
return m_angularStep;
|
||||
}
|
||||
|
||||
QPoint ViewportInteraction::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
|
||||
AzFramework::ScreenPoint ViewportInteraction::ViewportWorldToScreen(const AZ::Vector3& worldPosition)
|
||||
{
|
||||
auto pos = AzFramework::WorldToScreen(worldPosition, m_cameraState);
|
||||
return QPoint(pos.m_x, pos.m_y);
|
||||
return AzFramework::WorldToScreen(worldPosition, m_cameraState);
|
||||
}
|
||||
|
||||
void ViewportInteraction::SetCameraState(const AzFramework::CameraState& cameraState)
|
||||
@@ -117,12 +116,14 @@ namespace AzManipulatorTestFramework
|
||||
return m_viewportId;
|
||||
}
|
||||
|
||||
AZStd::optional<AZ::Vector3> ViewportInteraction::ViewportScreenToWorld([[maybe_unused]]const QPoint& screenPosition, [[maybe_unused]]float depth)
|
||||
AZStd::optional<AZ::Vector3> ViewportInteraction::ViewportScreenToWorld(
|
||||
[[maybe_unused]] const AzFramework::ScreenPoint& screenPosition, [[maybe_unused]] float depth)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportInteraction::ViewportScreenToWorldRay([[maybe_unused]]const QPoint& screenPosition)
|
||||
AZStd::optional<AzToolsFramework::ViewportInteraction::ProjectedViewportRay> ViewportInteraction::ViewportScreenToWorldRay(
|
||||
[[maybe_unused]] const AzFramework::ScreenPoint& screenPosition)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
-1
@@ -16,7 +16,6 @@
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/fixed_vector.h>
|
||||
|
||||
#include <AzFramework/API/AtomActiveInterface.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
namespace AzQtComponents
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
struct BehaviorParameter;
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
@@ -40,6 +46,8 @@ namespace AzToolsFramework
|
||||
};
|
||||
using GlobalFunctionCollection = AZStd::vector<GlobalFunction>;
|
||||
virtual void GetGlobalFunctionList(GlobalFunctionCollection& globalFunctionCollection) const = 0;
|
||||
|
||||
virtual AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) = 0;
|
||||
};
|
||||
|
||||
//! Interface to signal the phases for the Python virtual machine
|
||||
|
||||
+4
-9
@@ -10,8 +10,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <QPixmap>
|
||||
@@ -50,8 +50,8 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// FolderThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static constexpr const char* FolderIconPath = "Icons/AssetBrowser/Folder_16.svg";
|
||||
static constexpr const char* GemIconPath = "Icons/AssetBrowser/GemFolder_16.svg";
|
||||
static constexpr const char* FolderIconPath = "Assets/Editor/Icons/AssetBrowser/Folder_16.svg";
|
||||
static constexpr const char* GemIconPath = "Assets/Editor/Icons/AssetBrowser/GemFolder_16.svg";
|
||||
|
||||
FolderThumbnail::FolderThumbnail(SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
@@ -62,13 +62,8 @@ namespace AzToolsFramework
|
||||
auto folderKey = azrtti_cast<const FolderThumbnailKey*>(m_key.data());
|
||||
AZ_Assert(folderKey, "Incorrect key type, excpected FolderThumbnailKey");
|
||||
|
||||
const char* engineRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
|
||||
AZ_Assert(engineRoot, "Engine Root not initialized");
|
||||
const char* folderIcon = folderKey->IsGem() ? GemIconPath : FolderIconPath;
|
||||
AZStd::string absoluteIconPath;
|
||||
AZ::StringFunc::Path::Join(engineRoot, folderIcon, absoluteIconPath);
|
||||
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / folderIcon;
|
||||
m_pixmap.load(absoluteIconPath.c_str());
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
+6
-23
@@ -17,7 +17,7 @@
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/std/parallel/thread.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Asset/AssetBundleManifest.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
@@ -250,7 +250,7 @@ namespace AzToolsFramework
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(fileIO != nullptr, "AZ::IO::FileIOBase must be ready for use.\n");
|
||||
|
||||
AZStd::string bundleFilePath = assetBundleSettings.m_bundleFilePath;
|
||||
AZ::IO::Path bundleFilePath = AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) / assetBundleSettings.m_bundleFilePath;
|
||||
|
||||
AzFramework::PlatformId platformId = static_cast<AzFramework::PlatformId>(AzFramework::PlatformHelper::GetPlatformIndexFromName(assetBundleSettings.m_platform.c_str()));
|
||||
|
||||
@@ -259,22 +259,13 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* appRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
|
||||
|
||||
if (AzFramework::StringFunc::Path::IsRelative(bundleFilePath.c_str()))
|
||||
{
|
||||
AzFramework::StringFunc::Path::ConstructFull(appRoot, bundleFilePath.c_str(), bundleFilePath, true);
|
||||
}
|
||||
|
||||
AZ::u64 maxSizeInBytes = static_cast<AZ::u64>(assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB);
|
||||
AZ::u64 assetCatalogFileSizeBuffer = static_cast<AZ::u64>(AssetCatalogFileSizeBufferPercentage * assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB) / 100;
|
||||
AZ::u64 bundleSize = 0;
|
||||
AZ::u64 totalFileSize = 0;
|
||||
int bundleIndex = 0;
|
||||
|
||||
AZStd::string bundleFullPath = bundleFilePath;
|
||||
AZStd::string tempBundleFilePath = bundleFullPath + "_temp";
|
||||
AZStd::string tempBundleFilePath = bundleFilePath.Native() + "_temp";
|
||||
|
||||
AZStd::vector<AZStd::string> dependentBundleNames;
|
||||
AZStd::vector<AZStd::string> levelDirs;
|
||||
@@ -301,7 +292,7 @@ namespace AzToolsFramework
|
||||
if (fileIO->Exists(bundleFilePath.c_str()))
|
||||
{
|
||||
// This will delete both the parent bundle as well as all the dependent bundles mentioned in the manifest file of the parent bundle.
|
||||
if (!DeleteBundleFiles(bundleFilePath))
|
||||
if (!DeleteBundleFiles(bundleFilePath.Native()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -390,7 +381,7 @@ namespace AzToolsFramework
|
||||
// we need to find a bundle which does not exist on disk;
|
||||
bundleIndex++;
|
||||
numOfTries--;
|
||||
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath, bundleIndex);
|
||||
dependentBundleFileName = CreateAssetBundleFileName(bundleFilePath.Native(), bundleIndex);
|
||||
AzFramework::StringFunc::Path::ReplaceFullName(tempBundleFilePath, (dependentBundleFileName + tempBundleFileSuffix).c_str());
|
||||
} while (numOfTries && fileIO->Exists(tempBundleFilePath.c_str()));
|
||||
|
||||
@@ -463,15 +454,7 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
|
||||
AZStd::string assetFileInfoListPath = assetBundleSettings.m_assetFileInfoListPath;
|
||||
|
||||
const char* appRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot);
|
||||
|
||||
if (AzFramework::StringFunc::Path::IsRelative(assetFileInfoListPath.c_str()))
|
||||
{
|
||||
AzFramework::StringFunc::Path::ConstructFull(appRoot, assetFileInfoListPath.c_str(), assetFileInfoListPath, true);
|
||||
}
|
||||
AZ::IO::Path assetFileInfoListPath = AZ::IO::Path{ AZStd::string_view{AZ::Utils::GetEnginePath()} } / assetBundleSettings.m_assetFileInfoListPath;
|
||||
|
||||
if (!fileIO->Exists(assetFileInfoListPath.c_str()))
|
||||
{
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include <AzToolsFramework/UI/EditorEntityUi/EditorEntityUiSystemComponent.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorInteractionSystemComponent.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
@@ -93,7 +92,6 @@ namespace AzToolsFramework
|
||||
AzToolsFramework::SliceDependencyBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor(),
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::MaterialBrowser::MaterialBrowserComponent::CreateDescriptor(),
|
||||
AzToolsFramework::EditorInteractionSystemComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Components::EditorComponentAPIComponent::CreateDescriptor(),
|
||||
AzToolsFramework::Components::EditorLevelComponentAPIComponent::CreateDescriptor(),
|
||||
|
||||
+3
-4
@@ -127,8 +127,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
AZ::Transform worldFromLocal;
|
||||
AZ::TransformBus::EventResult(worldFromLocal, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM);
|
||||
@@ -402,10 +401,10 @@ namespace AzToolsFramework
|
||||
vertexIndex, localVertex);
|
||||
|
||||
const AZ::Vector3 worldVertex = worldFromLocal.TransformPoint(AZ::AdaptVertexOut<Vertex>(localVertex));
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, worldVertex);
|
||||
|
||||
// check if a vertex is inside the box select region
|
||||
if (editorBoxSelect.BoxRegion()->contains(screenPosition))
|
||||
if (editorBoxSelect.BoxRegion()->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
// see if vertexIndex is in active selection
|
||||
auto vertexIt = AZStd::find(
|
||||
|
||||
+3
-6
@@ -103,8 +103,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
m_startInternal = CalculateManipulationDataStart(
|
||||
worldFromLocalUniformScale, worldSurfacePosition, GetLocalPosition(),
|
||||
@@ -129,8 +128,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
@@ -150,8 +148,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, interaction.m_interactionId.m_viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(
|
||||
interaction.m_mousePick.m_screenCoordinates));
|
||||
interaction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(interaction.m_interactionId.m_viewportId);
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Data
|
||||
{
|
||||
struct AssetId;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
class MaterialBrowserRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
|
||||
// Only a single handler is allowed
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
|
||||
|
||||
virtual bool HasRecord(const AZ::Data::AssetId& assetId) = 0;
|
||||
virtual bool IsMultiMaterial(const AZ::Data::AssetId& assetId) = 0;
|
||||
};
|
||||
|
||||
using MaterialBrowserRequestBus = AZ::EBus<MaterialBrowserRequests>;
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
-65
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/FolderThumbnail.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/SourceThumbnail.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
|
||||
#include <AzToolsFramework/Thumbnails/SourceControlThumbnail.h>
|
||||
|
||||
#include <QApplication>
|
||||
AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QBrush::d': class 'QScopedPointer<QBrushData,QBrushDataPointerDeleter>' needs to have dll-interface to be used by clients of class 'QBrush'
|
||||
#include <QStyle>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
MaterialBrowserComponent::MaterialBrowserComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Activate()
|
||||
{
|
||||
using namespace Thumbnailer;
|
||||
using namespace AssetBrowser;
|
||||
const char* contextName = "MaterialBrowser";
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterContext, contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(FolderThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(MaterialThumbnailCache), contextName);
|
||||
ThumbnailerRequestsBus::Broadcast(&ThumbnailerRequests::RegisterThumbnailProvider, MAKE_TCACHE(SourceControlThumbnailCache), contextName);
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Deactivate()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<MaterialBrowserComponent, AZ::Component>();
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialBrowserComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97));
|
||||
}
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
//! MaterialBrowserComponent allows initialization of MaterialBrowser systems, such as thumbnails
|
||||
class MaterialBrowserComponent
|
||||
: public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(MaterialBrowserComponent, "{121F3F3B-2412-490D-9E3E-C205C677F476}")
|
||||
|
||||
MaterialBrowserComponent();
|
||||
virtual ~MaterialBrowserComponent() = default;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AZ::Component
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
};
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialThumbnail.h>
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
static constexpr const char* SimpleMaterialIconPath = ":/MaterialBrowser/images/material_04.png";
|
||||
static constexpr const char* MultiMaterialIconPath = ":/MaterialBrowser/images/material_06.png";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnail::MaterialThumbnail(Thumbnailer::SharedThumbnailKey key)
|
||||
: Thumbnail(key)
|
||||
{
|
||||
auto productKey = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(m_key.data());
|
||||
AZ_Assert(productKey, "Incorrect key type, excpected ProductThumbnailKey");
|
||||
|
||||
bool multiMat = false;
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat, &MaterialBrowserRequests::IsMultiMaterial, productKey->GetAssetId());
|
||||
|
||||
QString iconPath = multiMat ? MultiMaterialIconPath : SimpleMaterialIconPath;
|
||||
m_pixmap.load(iconPath);
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MaterialThumbnailCache
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
MaterialThumbnailCache::MaterialThumbnailCache()
|
||||
: ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>() {}
|
||||
|
||||
MaterialThumbnailCache::~MaterialThumbnailCache() = default;
|
||||
|
||||
int MaterialThumbnailCache::GetPriority() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* MaterialThumbnailCache::GetProviderName() const
|
||||
{
|
||||
return ProviderName;
|
||||
}
|
||||
|
||||
bool MaterialThumbnailCache::IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const
|
||||
{
|
||||
return azrtti_istypeof<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(key.data());
|
||||
}
|
||||
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
#include "MaterialBrowser/moc_MaterialThumbnail.cpp"
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/Thumbnails/Thumbnail.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Thumbnails/ProductThumbnail.h>
|
||||
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h>
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace MaterialBrowser
|
||||
{
|
||||
//! Material Browser uses only 2 thumbnails: simple and multimaterial
|
||||
class MaterialThumbnail
|
||||
: public Thumbnailer::Thumbnail
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MaterialThumbnail(Thumbnailer::SharedThumbnailKey key);
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
class MaterialKeyHash
|
||||
{
|
||||
public:
|
||||
size_t operator()(const Thumbnailer::SharedThumbnailKey& /*val*/) const
|
||||
{
|
||||
return 0; // there is only 2 thumbnails in this cache
|
||||
}
|
||||
};
|
||||
|
||||
class MaterialKeyEqual
|
||||
{
|
||||
public:
|
||||
bool operator()(const Thumbnailer::SharedThumbnailKey& val1, const Thumbnailer::SharedThumbnailKey& val2) const
|
||||
{
|
||||
auto productThumbnailKey1 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val1.data());
|
||||
auto productThumbnailKey2 = azrtti_cast<const AzToolsFramework::AssetBrowser::ProductThumbnailKey*>(val2.data());
|
||||
if (!productThumbnailKey1 || !productThumbnailKey2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// check whether keys point to single or multimaterial asset type
|
||||
bool multiMat1 = false;
|
||||
bool multiMat2 = false;
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat1, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey1->GetAssetId());
|
||||
MaterialBrowserRequestBus::BroadcastResult(multiMat2, &MaterialBrowserRequests::IsMultiMaterial, productThumbnailKey2->GetAssetId());
|
||||
return multiMat1 == multiMat2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//! MaterialBrowserEntry thumbnails
|
||||
class MaterialThumbnailCache
|
||||
: public Thumbnailer::ThumbnailCache<MaterialThumbnail, MaterialKeyHash, MaterialKeyEqual>
|
||||
{
|
||||
public:
|
||||
MaterialThumbnailCache();
|
||||
~MaterialThumbnailCache() override;
|
||||
|
||||
int GetPriority() const override;
|
||||
const char* GetProviderName() const override;
|
||||
|
||||
static constexpr const char* ProviderName = "CryMaterial Thumbnails";
|
||||
|
||||
protected:
|
||||
bool IsSupportedThumbnail(Thumbnailer::SharedThumbnailKey key) const override;
|
||||
};
|
||||
} // namespace MaterialBrowser
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
|
||||
@@ -96,9 +96,7 @@ namespace AzToolsFramework
|
||||
// target templates of the other instances.
|
||||
for (auto& nestedInstance : instances)
|
||||
{
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
nestedInstance->GetTemplateId(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
nestedInstance->GetInstanceAlias(), nestedInstance->GetLinkId(), undoBatch.GetUndoBatch());
|
||||
RemoveLink(nestedInstance, commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch());
|
||||
}
|
||||
|
||||
PrefabUndoHelpers::UpdatePrefabInstance(
|
||||
@@ -238,14 +236,9 @@ namespace AzToolsFramework
|
||||
|
||||
// Retrieve the owning instance of the common root entity, which will be our new instance's parent instance.
|
||||
commonRootEntityOwningInstance = GetOwnerInstanceByEntityId(commonRootEntityId);
|
||||
if (!commonRootEntityOwningInstance)
|
||||
{
|
||||
AZ_Assert(
|
||||
false,
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Failure(AZStd::string(
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided"));
|
||||
}
|
||||
AZ_Assert(
|
||||
commonRootEntityOwningInstance.has_value(),
|
||||
"Failed to create prefab : Couldn't get a valid owning instance for the common root entity of the enities provided");
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
@@ -287,6 +280,34 @@ namespace AzToolsFramework
|
||||
m_prefabUndoCache.Store(containerEntityId, AZStd::move(containerEntityDomAfter));
|
||||
}
|
||||
|
||||
void PrefabPublicHandler::RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
LinkReference nestedInstanceLink = m_prefabSystemComponentInterface->FindLink(sourceInstance->GetLinkId());
|
||||
AZ_Assert(
|
||||
nestedInstanceLink.has_value(),
|
||||
"A valid link was not found for one of the instances provided as input for the CreatePrefab operation.");
|
||||
|
||||
PrefabDomReference nestedInstanceLinkDom = nestedInstanceLink->get().GetLinkDom();
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkDom.has_value(),
|
||||
"A valid DOM was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDomValueReference nestedInstanceLinkPatches =
|
||||
PrefabDomUtils::FindPrefabDomValue(nestedInstanceLinkDom->get(), PrefabDomUtils::PatchesName);
|
||||
AZ_Assert(
|
||||
nestedInstanceLinkPatches.has_value(),
|
||||
"A valid DOM for patches was not found for the link corresponding to one of the instances provided as input for the "
|
||||
"CreatePrefab operation.");
|
||||
|
||||
PrefabDom patchesCopyForUndoSupport;
|
||||
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
|
||||
patchesCopyForUndoSupport, undoBatch);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
{
|
||||
auto templateId = m_prefabSystemComponentInterface->GetTemplateIdFromFilePath(filePath.c_str());
|
||||
|
||||
@@ -82,6 +82,16 @@ namespace AzToolsFramework
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
|
||||
/**
|
||||
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
|
||||
*
|
||||
* \param sourceInstance The instance corresponding to the source template of the link to be removed.
|
||||
* \param targetTemplateId The id of the target template of the link to be removed.
|
||||
* \param undoBatch The undo batch to set as parent for this remove link action.
|
||||
*/
|
||||
void RemoveLink(
|
||||
AZStd::unique_ptr<Instance>& sourceInstance, TemplateId targetTemplateId, UndoSystem::URSequencePoint* undoBatch);
|
||||
|
||||
/**
|
||||
* Given a list of entityIds, finds the prefab instance that owns the common root entity of the entityIds.
|
||||
*
|
||||
|
||||
@@ -663,8 +663,9 @@ namespace AzToolsFramework
|
||||
newLink.SetSourceTemplateId(linkSourceId);
|
||||
newLink.SetInstanceName(instanceAlias.c_str());
|
||||
newLink.GetLinkDom().SetObject();
|
||||
newLink.GetLinkDom().AddMember(rapidjson::StringRef(PrefabDomUtils::SourceName),
|
||||
rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()), newLink.GetLinkDom().GetAllocator());
|
||||
newLink.GetLinkDom().AddMember(
|
||||
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
|
||||
newLink.GetLinkDom().GetAllocator());
|
||||
|
||||
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
|
||||
{
|
||||
@@ -770,8 +771,8 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
#if defined(AZ_ENABLE_TRACING)
|
||||
Template& sourceTemplate = sourceTemplateReference->get();
|
||||
Template& targetTemplate = targetTemplateReference->get();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace AzToolsFramework
|
||||
, m_sourceId(InvalidTemplateId)
|
||||
, m_instanceAlias("")
|
||||
, m_linkId(InvalidLinkId)
|
||||
, m_linkDom(PrefabDom())
|
||||
, m_linkPatches(PrefabDom())
|
||||
, m_linkStatus(LinkStatus::LINKSTATUS)
|
||||
{
|
||||
m_prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom,
|
||||
PrefabDomReference linkPatches,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
@@ -132,9 +132,9 @@ namespace AzToolsFramework
|
||||
m_instanceAlias = instanceAlias;
|
||||
m_linkId = linkId;
|
||||
|
||||
if (linkDom.has_value())
|
||||
if (linkPatches.has_value())
|
||||
{
|
||||
m_linkDom = AZStd::move(linkDom->get());
|
||||
m_linkPatches = AZStd::move(linkPatches->get());
|
||||
}
|
||||
|
||||
//if linkId is invalid, set as ADD
|
||||
@@ -193,7 +193,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabUndoInstanceLink::AddLink()
|
||||
{
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkDom, m_linkId);
|
||||
m_linkId = m_prefabSystemComponentInterface->CreateLink(m_targetId, m_sourceId, m_instanceAlias, m_linkPatches, m_linkId);
|
||||
}
|
||||
|
||||
void PrefabUndoInstanceLink::RemoveLink()
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkDom = PrefabDomReference(),
|
||||
PrefabDomReference linkPatches = PrefabDomReference(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
@@ -120,7 +120,7 @@ namespace AzToolsFramework
|
||||
InstanceAlias m_instanceAlias;
|
||||
|
||||
LinkId m_linkId;
|
||||
PrefabDom m_linkDom; //data for delete/update
|
||||
PrefabDom m_linkPatches; //data for delete/update
|
||||
LinkStatus m_linkStatus;
|
||||
|
||||
PrefabSystemComponentInterface* m_prefabSystemComponentInterface = nullptr;
|
||||
|
||||
@@ -46,13 +46,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch)
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
PrefabDom emptyLinkDom;
|
||||
linkRemoveUndo->Capture(
|
||||
targetTemplateId, sourceTemplateId, instanceAlias, emptyLinkDom, linkId);
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace AzToolsFramework
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias,
|
||||
LinkId linkId, UndoSystem::URSequencePoint* undoBatch);
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzToolsFramework/Thumbnails/LoadingThumbnail.h>
|
||||
#include <AzFramework/Application/Application.h>
|
||||
|
||||
@@ -23,18 +23,14 @@ namespace AzToolsFramework
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// LoadingThumbnail
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static const char* LoadingIconPath = "Icons/AssetBrowser/in_progress.gif";
|
||||
static constexpr const char* LoadingIconPath = "Assets/Editor/Icons/AssetBrowser/in_progress.gif";
|
||||
|
||||
LoadingThumbnail::LoadingThumbnail()
|
||||
: Thumbnail(MAKE_TKEY(ThumbnailKey))
|
||||
, m_angle(0)
|
||||
{
|
||||
const char* engineRoot = nullptr;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
|
||||
AZ_Assert(engineRoot, "Engine Root not initialized");
|
||||
AZStd::string iconPath;
|
||||
AZ::StringFunc::Path::Join(engineRoot, LoadingIconPath, iconPath);
|
||||
m_loadingMovie.setFileName(iconPath.c_str());
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / LoadingIconPath;
|
||||
m_loadingMovie.setFileName(absoluteIconPath.c_str());
|
||||
m_loadingMovie.setCacheMode(QMovie::CacheMode::CacheAll);
|
||||
m_loadingMovie.setScaledSize(QSize(LoadingThumbnailSize, LoadingThumbnailSize));
|
||||
m_loadingMovie.start();
|
||||
|
||||
@@ -10,18 +10,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Thumbnails/MissingThumbnail.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace Thumbnailer
|
||||
{
|
||||
static const char* MISSING_ICON_PATH = "Icons/AssetBrowser/Default_16.svg";
|
||||
static constexpr const char* MissingIconPath = "Assets/Editor/Icons/AssetBrowser/Default_16.svg";
|
||||
|
||||
MissingThumbnail::MissingThumbnail()
|
||||
: Thumbnail(MAKE_TKEY(ThumbnailKey))
|
||||
{
|
||||
m_pixmap.load(MISSING_ICON_PATH);
|
||||
auto absoluteIconPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / MissingIconPath;
|
||||
m_pixmap.load(absoluteIconPath.c_str());
|
||||
m_state = m_pixmap.isNull() ? State::Failed : State::Ready;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportTypes.h>
|
||||
|
||||
class QPoint; // LYN-2315 in-progress, remove this
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
struct ScreenPoint;
|
||||
@@ -167,14 +165,14 @@ namespace AzToolsFramework
|
||||
/// Return the angle snapping/step size.
|
||||
virtual float AngleStep() = 0;
|
||||
/// Transform a point in world space to screen space coordinates.
|
||||
virtual QPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
virtual AzFramework::ScreenPoint ViewportWorldToScreen(const AZ::Vector3& worldPosition) = 0;
|
||||
/// Transform a point in screen space coordinates to a vector in world space based on clip space depth.
|
||||
/// Depth specifies a relative camera depth to project in the range of [0.f, 1.f].
|
||||
/// Returns the world space position if successful.
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const QPoint& screenPosition, float depth) = 0;
|
||||
virtual AZStd::optional<AZ::Vector3> ViewportScreenToWorld(const AzFramework::ScreenPoint& screenPosition, float depth) = 0;
|
||||
/// Casts a point in screen space to a ray in world space originating from the viewport camera frustum's near plane.
|
||||
/// Returns a ray containing the ray's origin and a direction normal, if successful.
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const QPoint& screenPosition) = 0;
|
||||
virtual AZStd::optional<ProjectedViewportRay> ViewportScreenToWorldRay(const AzFramework::ScreenPoint& screenPosition) = 0;
|
||||
|
||||
protected:
|
||||
~ViewportInteractionRequests() = default;
|
||||
@@ -207,9 +205,9 @@ namespace AzToolsFramework
|
||||
public:
|
||||
/// Given a point in screen space, return the picked entity (if any).
|
||||
/// Picked EntityId will be returned, InvalidEntityId will be returned on failure.
|
||||
virtual AZ::EntityId PickEntity(const QPoint& point) = 0;
|
||||
virtual AZ::EntityId PickEntity(const AzFramework::ScreenPoint& point) = 0;
|
||||
/// Given a point in screen space, return the terrain position in world space.
|
||||
virtual AZ::Vector3 PickTerrain(const QPoint& point) = 0;
|
||||
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;
|
||||
/// Given the current view frustum (viewport) return all visible entities.
|
||||
@@ -277,20 +275,6 @@ namespace AzToolsFramework
|
||||
|
||||
} // namespace ViewportInteraction
|
||||
|
||||
/// Temporary bus to query if the new Viewport Interaction Model mode is enabled or not.
|
||||
class NewViewportInteractionModelEnabledRequests
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
virtual bool IsNewViewportInteractionModelEnabled() = 0;
|
||||
|
||||
protected:
|
||||
~NewViewportInteractionModelEnabledRequests() = default;
|
||||
};
|
||||
|
||||
/// Type to inherit to implement NewViewportInteractionModelEnabledRequests
|
||||
using NewViewportInteractionModelEnabledRequestBus = AZ::EBus<NewViewportInteractionModelEnabledRequests>;
|
||||
|
||||
/// Utility function to return EntityContextId.
|
||||
inline AzFramework::EntityContextId GetEntityContextId()
|
||||
{
|
||||
@@ -300,16 +284,4 @@ namespace AzToolsFramework
|
||||
|
||||
return entityContextId;
|
||||
}
|
||||
|
||||
/// Utility function to return if the new Viewport Interaction Model
|
||||
/// is enabled (wraps NewViewportInteractionModelEnabledRequests).
|
||||
inline bool IsNewViewportInteractionModelEnabled()
|
||||
{
|
||||
bool newViewportInteractionModelEnabled = false;
|
||||
NewViewportInteractionModelEnabledRequestBus::BroadcastResult(
|
||||
newViewportInteractionModelEnabled,
|
||||
&NewViewportInteractionModelEnabledRequests::IsNewViewportInteractionModelEnabled);
|
||||
|
||||
return newViewportInteractionModelEnabled;
|
||||
}
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
+5
-5
@@ -141,16 +141,16 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& entityPosition = m_entityDataCache->GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
// selecting based on 2d icon - should only do it when visible and not selected
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
const float distSqFromCamera = cameraState.m_position.GetDistanceSq(entityPosition);
|
||||
const auto iconRange = static_cast<float>(GetIconScale(distSqFromCamera) * s_iconSize * 0.5f);
|
||||
const auto screenCoords = mouseInteraction.m_mouseInteraction.m_mousePick.m_screenCoordinates;
|
||||
|
||||
if ( screenCoords.m_x >= screenPosition.x() - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.x() + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.y() - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.y() + iconRange)
|
||||
if ( screenCoords.m_x >= screenPosition.m_x - iconRange
|
||||
&& screenCoords.m_x <= screenPosition.m_x + iconRange
|
||||
&& screenCoords.m_y >= screenPosition.m_y - iconRange
|
||||
&& screenCoords.m_y <= screenPosition.m_y + iconRange)
|
||||
{
|
||||
entityIdUnderCursor = entityId;
|
||||
break;
|
||||
|
||||
+2
-2
@@ -53,11 +53,11 @@ namespace AzToolsFramework
|
||||
return AZ::GetMax(projectedCameraDistance, cameraState.m_nearClip) / apparentDistance;
|
||||
}
|
||||
|
||||
QPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
AzFramework::ScreenPoint GetScreenPosition(const int viewportId, const AZ::Vector3& worldTranslation)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
QPoint screenPosition = QPoint();
|
||||
auto screenPosition = AzFramework::ScreenPoint(0, 0);
|
||||
ViewportInteraction::ViewportInteractionRequestBus::EventResult(
|
||||
screenPosition, viewportId,
|
||||
&ViewportInteraction::ViewportInteractionRequestBus::Events::ViewportWorldToScreen,
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ namespace AzToolsFramework
|
||||
const AZ::Vector3& worldPosition, const AzFramework::CameraState& cameraState);
|
||||
|
||||
/// Map from world space to screen space.
|
||||
QPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
AzFramework::ScreenPoint GetScreenPosition(int viewportId, const AZ::Vector3& worldTranslation);
|
||||
|
||||
/// Given a mouse interaction, determine if the pick ray from its position
|
||||
/// in screen space intersected an aabb in world space.
|
||||
|
||||
+4
-4
@@ -316,14 +316,14 @@ namespace AzToolsFramework
|
||||
|
||||
template<typename EntitySelectFuncType, typename EntityIdContainer, typename Compare>
|
||||
static void BoxSelectAddRemoveToEntitySelection(
|
||||
const AZStd::optional<QRect>& boxSelect, const QPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const AZStd::optional<QRect>& boxSelect, const AzFramework::ScreenPoint& screenPosition, const AZ::EntityId visibleEntityId,
|
||||
const EntityIdContainer& incomingEntityIds, EntityIdContainer& outgoingEntityIds,
|
||||
EditorTransformComponentSelection& entityTransformComponentSelection,
|
||||
EntitySelectFuncType selectFunc1, EntitySelectFuncType selectFunc2, Compare outgoingCheck)
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework);
|
||||
|
||||
if (boxSelect->contains(screenPosition))
|
||||
if (boxSelect->contains(ViewportInteraction::QPointFromScreenPoint(screenPosition)))
|
||||
{
|
||||
const auto entityIt = incomingEntityIds.find(visibleEntityId);
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace AzToolsFramework
|
||||
const AZ::EntityId entityId = entityDataCache.GetVisibleEntityId(entityCacheIndex);
|
||||
const AZ::Vector3& entityPosition = entityDataCache.GetVisibleEntityPosition(entityCacheIndex);
|
||||
|
||||
const QPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
const AzFramework::ScreenPoint screenPosition = GetScreenPosition(viewportId, entityPosition);
|
||||
|
||||
if (currentKeyboardModifiers.Ctrl())
|
||||
{
|
||||
@@ -927,7 +927,7 @@ namespace AzToolsFramework
|
||||
ViewportInteraction::MainEditorViewportInteractionRequestBus::EventResult(
|
||||
worldSurfacePosition, viewportId,
|
||||
&ViewportInteraction::MainEditorViewportInteractionRequestBus::Events::PickTerrain,
|
||||
ViewportInteraction::QPointFromScreenPoint(mouseInteraction.m_mousePick.m_screenCoordinates));
|
||||
mouseInteraction.m_mousePick.m_screenCoordinates);
|
||||
|
||||
// convert to local space - snap if enabled
|
||||
const GridSnapParameters gridSnapParams = GridSnapSettings(viewportId);
|
||||
|
||||
@@ -70,11 +70,6 @@ set(FILES
|
||||
AssetCatalog/PlatformAddressedAssetCatalog.cpp
|
||||
AssetCatalog/PlatformAddressedAssetCatalogManager.h
|
||||
AssetCatalog/PlatformAddressedAssetCatalogManager.cpp
|
||||
MaterialBrowser/MaterialBrowserBus.h
|
||||
MaterialBrowser/MaterialBrowserComponent.cpp
|
||||
MaterialBrowser/MaterialBrowserComponent.h
|
||||
MaterialBrowser/MaterialThumbnail.cpp
|
||||
MaterialBrowser/MaterialThumbnail.h
|
||||
Thumbnails/ThumbnailerComponent.cpp
|
||||
Thumbnails/ThumbnailerComponent.h
|
||||
Thumbnails/LoadingThumbnail.cpp
|
||||
|
||||
Reference in New Issue
Block a user