Merged main in

This commit is contained in:
Aristo7
2021-05-04 10:13:50 -05:00
427 changed files with 9465 additions and 26529 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ public:
Matrix34 m_matInv;
Vec3 m_eyePosInWS;
Vec3 m_eyePosInOS;
Plane m_volumeTraceStartPlane;
Plane_tpl<f32> m_volumeTraceStartPlane;
AABB m_renderBoundsOS;
bool m_viewerInsideVolume;
bool m_nearPlaneIntersectsVolume;
+1 -1
View File
@@ -25,7 +25,7 @@ public:
virtual void mfPrepare(bool bCheckOverflow);
virtual bool mfDraw(CShader* ef, SShaderPass* sfm);
virtual void mfGetPlane(Plane& pl);
virtual void mfGetPlane(Plane_tpl<f32>& pl);
virtual void Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof);
void ReleaseOcean();
+2 -2
View File
@@ -27,7 +27,7 @@ public:
virtual ~CREWaterVolume();
virtual void mfPrepare(bool bCheckOverflow);
virtual bool mfDraw(CShader* ef, SShaderPass* sfm);
virtual void mfGetPlane(Plane& pl);
virtual void mfGetPlane(Plane_tpl<f32>& pl);
virtual void mfCenter(Vec3& vCenter, CRenderObject* pObj);
virtual void GetMemoryUsage(ICrySizer* pSizer) const
@@ -69,7 +69,7 @@ public:
Vec3 m_center;
AABB m_WSBBox;
Plane m_fogPlane;
Plane_tpl<f32> m_fogPlane;
float m_fogDensity;
Vec3 m_fogColor;
bool m_fogColorAffectedBySun;
+9 -9
View File
@@ -594,7 +594,7 @@ public:
ILINE const Vec3& GetFPVertex(int nId) const; //get far-plane vertices
ILINE const Vec3& GetPPVertex(int nId) const; //get projection-plane vertices
ILINE const Plane* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; }
ILINE const Plane_tpl<f32>* GetFrustumPlane(int numplane) const { return &m_fp[numplane]; }
//////////////////////////////////////////////////////////////////////////
// Z-Buffer ranges.
@@ -720,7 +720,7 @@ private:
Vec3 m_cltn, m_crtn, m_clbn, m_crbn; //this are the 4 vertices of the near-plane in cam-space
Vec3 m_cltf, m_crtf, m_clbf, m_crbf; //this are the 4 vertices of the farclip-plane in cam-space
Plane m_fp [FRUSTUM_PLANES]; //
Plane_tpl<f32> m_fp [FRUSTUM_PLANES]; //
uint32 m_idx1[FRUSTUM_PLANES], m_idy1[FRUSTUM_PLANES], m_idz1[FRUSTUM_PLANES]; //
uint32 m_idx2[FRUSTUM_PLANES], m_idy2[FRUSTUM_PLANES], m_idz2[FRUSTUM_PLANES]; //
@@ -742,7 +742,7 @@ public:
m_crtp = arrvVerts[2];
m_crbp = arrvVerts[3];
}
inline void SetFrustumPlane(int i, const Plane& plane)
inline void SetFrustumPlane(int i, const Plane_tpl<f32>& plane)
{
m_fp[i] = plane;
//do not break strict aliasing rules, use union instead of reinterpret_casts
@@ -1180,12 +1180,12 @@ inline void CCamera::UpdateFrustum()
//-------------------------------------------------------------------------------
//--- calculate the six frustum-planes using the frustum edges in world-space ---
//-------------------------------------------------------------------------------
m_fp[FR_PLANE_NEAR ] = Plane::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition());
m_fp[FR_PLANE_RIGHT ] = Plane::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition());
m_fp[FR_PLANE_LEFT ] = Plane::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_TOP ] = Plane::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition());
m_fp[FR_PLANE_BOTTOM] = Plane::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_FAR ] = Plane::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane
m_fp[FR_PLANE_NEAR ] = Plane_tpl<f32>::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition());
m_fp[FR_PLANE_RIGHT ] = Plane_tpl<f32>::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition());
m_fp[FR_PLANE_LEFT ] = Plane_tpl<f32>::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_TOP ] = Plane_tpl<f32>::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition());
m_fp[FR_PLANE_BOTTOM] = Plane_tpl<f32>::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition());
m_fp[FR_PLANE_FAR ] = Plane_tpl<f32>::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane
uint32 rh = m_Matrix.IsOrthonormalRH();
if (rh == 0)
@@ -1168,17 +1168,6 @@ namespace Distance {
return fDist2;
}
// Compute both the min and max distances of a box to a plane, in the sense of the plane normal.
inline void AABB_Plane(float* pfDistMin, float* pfDistMax, const AABB& box, const Plane& pl)
{
float fDist0 = pl.DistFromPlane(box.min),
fDistX = (box.max.x - box.min.x) * pl.n.x,
fDistY = (box.max.y - box.min.y) * pl.n.y,
fDistZ = (box.max.z - box.min.z) * pl.n.z;
*pfDistMin = fDist0 + min(fDistX, 0.f) + min(fDistY, 0.f) + min(fDistZ, 0.f);
*pfDistMax = fDist0 + max(fDistX, 0.f) + max(fDistY, 0.f) + max(fDistZ, 0.f);
}
//----------------------------------------------------------------------------------
// Distance: Sphere_Triangle
//----------------------------------------------------------------------------------
+2 -2
View File
@@ -22,7 +22,7 @@
#include <Cry_Geo.h>
namespace Intersect {
inline bool Ray_Plane(const Ray& ray, const Plane& plane, Vec3& output, bool bSingleSidePlane = true)
inline bool Ray_Plane(const Ray& ray, const Plane_tpl<f32>& plane, Vec3& output, bool bSingleSidePlane = true)
{
float cosine = plane.n | ray.direction;
@@ -49,7 +49,7 @@ namespace Intersect {
return true; //intersection occurred
}
inline bool Line_Plane(const Line& line, const Plane& plane, Vec3& output, bool bSingleSidePlane = true)
inline bool Line_Plane(const Line& line, const Plane_tpl<f32>& plane, Vec3& output, bool bSingleSidePlane = true)
{
float cosine = plane.n | line.direction;
+2 -25
View File
@@ -945,29 +945,6 @@ namespace Overlap {
}
}
/*!
*
* we use the SEPARATING-AXIS-TEST for OBB/Plane overlap.
*
* Example:
* bool result=Overlap::OBB_Plane( pos,obb, plane );
*
*/
inline bool OBB_Plane(const Vec3& pos, const OBB& obb, const Plane& plane)
{
//the new center-position in world-space
Vec3 p = obb.m33 * obb.c + pos;
//extract the orientation-vectors from the columns of the 3x3 matrix
//and scale them by the half-lengths
Vec3 ax = Vec3(obb.m33.m00, obb.m33.m10, obb.m33.m20) * obb.h.x;
Vec3 ay = Vec3(obb.m33.m01, obb.m33.m11, obb.m33.m21) * obb.h.y;
Vec3 az = Vec3(obb.m33.m02, obb.m33.m12, obb.m33.m22) * obb.h.z;
//check OBB against Plane, using the plane-normal as separating axis
return fabsf(plane | p) < (fabsf(plane.n | ax) + fabsf(plane.n | ay) + fabsf(plane.n | az));
}
/*!
*
* we use the SEPARATING AXIS TEST to check if a triangle and AABB overlap.
@@ -1214,7 +1191,7 @@ namespace Overlap {
//test if the box intersects the plane of the triangle
//compute plane equation of triangle: normal*x+d=0
Plane plane = Plane::CreatePlane((e0 % e1), v0);
Plane_tpl<f32> plane = Plane_tpl<f32>::CreatePlane((e0 % e1), v0);
Vec3 vmin, vmax;
if (plane.n.x > 0.0f)
@@ -1505,7 +1482,7 @@ namespace Overlap {
//test if the box overlaps the plane of the triangle
//compute plane equation of triangle: normal*x+d=0
Plane plane = Plane::CreatePlane((e0 % e1), v0);
Plane_tpl<f32> plane = Plane_tpl<f32>::CreatePlane((e0 % e1), v0);
Vec3 vmin, vmax;
if (plane.n.x > 0.0f)
+1 -1
View File
@@ -458,7 +458,7 @@ struct SClipVolumeBlendInfo
{
static const int BlendPlaneCount = 2;
Plane blendPlanes[BlendPlaneCount];
Plane_tpl<f32> blendPlanes[BlendPlaneCount];
struct IClipVolume* blendVolumes[BlendPlaneCount];
};
@@ -731,8 +731,8 @@ struct IWaterVolumeRenderNode
virtual void SetAuxPhysParams(pe_params_area*) = 0;
virtual void CreateOcean(uint64 volumeID, /* TBD */ bool keepSerializationParams = false) = 0;
virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateArea(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, const Vec2& surfUVScale, const Plane_tpl<f32>& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const Vec3* pVertices, unsigned int numVertices, float uTexCoordBegin, float uTexCoordEnd, const Vec2& surfUVScale, const Plane_tpl<f32>& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void CreateRiver(uint64 volumeID, const AZStd::vector<AZ::Vector3>& verticies, const AZ::Transform& transform, float uTexCoordBegin, float uTexCoordEnd, const AZ::Vector2& surfUVScale, const AZ::Plane& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0;
virtual void SetAreaPhysicsArea(const Vec3* pVertices, unsigned int numVertices, bool keepSerializationParams = false) = 0;
-1
View File
@@ -52,7 +52,6 @@ struct SShaderItem;
class ITexture;
struct IMaterial;
struct SParam;
class CMaterial;
struct SShaderSerializeContext;
struct IAnimNode;
struct SSkinningData;
+2 -2
View File
@@ -119,7 +119,7 @@ struct IRenderElement
virtual void mfCenter(Vec3& centr, CRenderObject* pObj) = 0;
virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs) = 0;
virtual void mfReset() = 0;
virtual void mfGetPlane(Plane& pl) = 0;
virtual void mfGetPlane(Plane_tpl<f32>& pl) = 0;
virtual void mfExport(struct SShaderSerializeContext& SC) = 0;
virtual void mfImport(struct SShaderSerializeContext& SC, uint32& offset) = 0;
virtual void mfPrecache(const SShaderItem& SH) = 0;
@@ -265,7 +265,7 @@ public:
void mfPrecache([[maybe_unused]] const SShaderItem& SH) override {}
void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) override { CryFatalError("mfExport has not been implemented for this render element type"); }
void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) override { CryFatalError("mfImport has not been implemented for this render element type"); }
void mfGetPlane(Plane& pl) override;
void mfGetPlane(Plane_tpl<f32>& pl) override;
void* mfGetPointer([[maybe_unused]] ESrcPointer ePT, [[maybe_unused]] int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) override { return nullptr; }
uint16 mfGetFlags() override { return m_Flags; }
@@ -231,6 +231,18 @@ namespace AZ
//! Compound assignment operator for matrix-matrix multiplication.
Matrix3x4& operator*=(const Matrix3x4& rhs);
//! Operator for matrix-matrix addition.
[[nodiscard]] Matrix3x4 operator+(const Matrix3x4& rhs) const;
//! Compound assignment operator for matrix-matrix addition.
Matrix3x4& operator+=(const Matrix3x4& rhs);
//! Operator for multiplying all matrix's elements with a scalar
[[nodiscard]] Matrix3x4 operator*(float scalar) const;
//! Compound assignment operator for multiplying all matrix's elements with a scalar
Matrix3x4& operator*=(float scalar);
//! Operator for transforming a Vector3.
[[nodiscard]] Vector3 operator*(const Vector3& rhs) const;
@@ -274,12 +286,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;
@@ -487,6 +487,43 @@ 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*(float scalar) const
{
const Vector4 vector4Scalar(scalar);
return Matrix3x4
(
Simd::Vec4::Mul(m_rows[0].GetSimdValue(), vector4Scalar.GetSimdValue()),
Simd::Vec4::Mul(m_rows[1].GetSimdValue(), vector4Scalar.GetSimdValue()),
Simd::Vec4::Mul(m_rows[2].GetSimdValue(), vector4Scalar.GetSimdValue())
);
}
AZ_MATH_INLINE Matrix3x4& Matrix3x4::operator*=(float scalar)
{
*this = *this * scalar;
return *this;
}
AZ_MATH_INLINE Vector3 Matrix3x4::operator*(const Vector3& rhs) const
{
return Vector3
@@ -583,6 +620,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 +643,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();
@@ -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)
@@ -484,6 +484,38 @@ namespace UnitTest
EXPECT_TRUE(matrix5.IsClose(matrix1 * matrix4));
}
TEST(MATH_Matrix3x4, AddMatrix3x4)
{
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;
EXPECT_THAT(matrix1 + (matrix2 + matrix3), IsClose((matrix1 + matrix2) + matrix3));
EXPECT_THAT(matrix2 + AZ::Matrix3x4::CreateZero(), IsClose(matrix2));
EXPECT_THAT(matrix3 + AZ::Matrix3x4::CreateZero(), IsClose(AZ::Matrix3x4::CreateZero() + matrix3));
EXPECT_THAT(matrix3 + matrix3, IsClose(matrix3 * 2.0f));
EXPECT_THAT(matrix5, IsClose(matrix1 + matrix4));
}
TEST(MATH_Matrix3x4, MultiplyByScalar)
{
const AZ::Vector4 row0(1.488f, 2.56f, 0.096f, 2.3f);
const AZ::Vector4 row1(0.384f, -1.92f, 0.428f, -1.6f);
const AZ::Vector4 row2(1.28f, -2.4f, -0.24f, 3.7f);
const float scalar = 3.2f;
const AZ::Vector4 row0Result = row0 * scalar;
const AZ::Vector4 row1Result = row1 * scalar;
const AZ::Vector4 row2Result = row2 * scalar;
AZ::Matrix3x4 matrix = AZ::Matrix3x4::CreateFromRows(row0, row1, row2);
EXPECT_THAT(matrix * 0.0f, IsClose(AZ::Matrix3x4::CreateZero()));
EXPECT_THAT(matrix * 1.0f, IsClose(matrix));
EXPECT_THAT(matrix * scalar, IsClose(AZ::Matrix3x4::CreateFromRows(row0Result, row1Result, row2Result)));
EXPECT_THAT(matrix * 2.0f, IsClose(matrix + matrix));
}
TEST(MATH_Matrix3x4, MultiplyByVector3)
{
const AZ::Vector4 row0(1.488f, 2.56f, 0.096f, 2.3f);
@@ -652,6 +684,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)
@@ -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;
@@ -12,14 +12,19 @@
#include "CameraInput.h"
#include <AzCore/Console/IConsole.h>
#include <AzCore/Math/MathUtils.h>
#include <AzCore/Math/Plane.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/Windowing/WindowBus.h>
AZ_CVAR(
float, ed_newCameraSystemDefaultPlaneHeight, 34.0f, nullptr, AZ::ConsoleFunctorFlags::Null,
"The default height of the ground plane to do intersection tests against when orbiting");
namespace AzFramework
{
void CameraSystem::HandleEvents(const InputEvent& event)
bool CameraSystem::HandleEvents(const InputEvent& event)
{
if (const auto& cursor_motion = AZStd::get_if<CursorMotionEvent>(&event))
{
@@ -30,10 +35,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 +56,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 +103,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++;
}
}
@@ -154,14 +164,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) * m_props.m_rotateSpeed;
nextCamera.m_yaw -= float(cursorDelta.m_x) * m_props.m_rotateSpeed;
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;
}
@@ -190,18 +200,18 @@ 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 * m_props.m_panSpeed;
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * m_props.m_panSpeed;
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(m_props.m_panInvertX);
nextCamera.m_lookAt += deltaPanY * -inv(m_props.m_panInvertY);
return nextCamera;
}
@@ -285,10 +295,10 @@ 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);
@@ -344,10 +354,6 @@ namespace AzFramework
{
if (input->m_channelId == InputDeviceKeyboard::Key::ModifierAltL)
{
if (input->m_state == InputChannel::State::Updated)
{
goto end;
}
if (input->m_state == InputChannel::State::Began)
{
BeginActivation();
@@ -358,7 +364,7 @@ namespace AzFramework
}
}
}
end:
if (Active())
{
m_orbitCameras.HandleEvents(event);
@@ -366,16 +372,18 @@ 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_newCameraSystemDefaultPlaneHeight))
.CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance))
{
hit_distance = AZStd::min(hit_distance, m_props.m_maxOrbitDistance);
nextCamera.m_lookDist = -hit_distance;
nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance;
}
@@ -388,7 +396,6 @@ namespace AzFramework
if (Active())
{
// todo: need to return nested cameras to idle state when ending
nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
}
@@ -413,7 +420,7 @@ 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);
@@ -457,7 +464,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;
@@ -477,25 +484,26 @@ namespace AzFramework
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 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);
camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT);
const float moveRate = std::exp2(props.m_moveSmoothness);
const float moveT = std::exp2(-moveRate * deltaTime);
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT);
@@ -508,6 +516,11 @@ namespace AzFramework
const auto& inputChannelId = inputChannel.GetInputChannelId();
const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
const bool wasMouseButton =
AZStd::any_of(InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), [inputChannelId](const auto& button) {
return button == inputChannelId;
});
if (inputChannelId == InputDeviceMouse::SystemCursorPosition)
{
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
@@ -521,7 +534,7 @@ namespace AzFramework
{
return ScrollEvent{inputChannel.GetValue()};
}
else if (InputDeviceMouse::IsMouseDevice(inputDeviceId) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
else if ((InputDeviceMouse::IsMouseDevice(inputDeviceId) && wasMouseButton) || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId))
{
return DiscreteInputEvent{inputChannelId, inputChannel.GetState()};
}
@@ -12,6 +12,7 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Math/Matrix3x3.h>
#include <AzCore/Math/Transform.h>
#include <AzCore/std/containers/variant.h>
@@ -20,11 +21,28 @@
#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;
// to be moved
class ModernViewportCameraControllerRequests : public AZ::EBusTraits
{
public:
using BusIdType = AzFramework::ViewportId; ///< ViewportId - used to address requests to this EBus.
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
virtual void SetTargetCameraTransform(const AZ::Transform& transform) = 0;
protected:
~ModernViewportCameraControllerRequests() = default;
};
using ModernViewportCameraControllerRequestBus = AZ::EBus<ModernViewportCameraControllerRequests>;
struct Camera
{
AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero,
@@ -51,8 +69,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
@@ -171,7 +189,7 @@ namespace AzFramework
{
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 +201,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;
@@ -308,7 +326,7 @@ namespace AzFramework
enum class TranslationType
{
// clang-format off
Nil = 0,
Nil = 0,
Forward = 1 << 0,
Backward = 1 << 1,
Left = 1 << 2,
@@ -369,7 +387,7 @@ namespace AzFramework
struct Props
{
float m_dollySpeed = 0.2f;
float m_dollySpeed = 0.02f;
} m_props;
};
@@ -393,7 +411,7 @@ namespace AzFramework
struct Props
{
float m_translateSpeed = 0.2f;
float m_translateSpeed = 0.02f;
} m_props;
};
@@ -411,7 +429,7 @@ namespace AzFramework
struct Props
{
float m_defaultOrbitDistance = 15.0f;
float m_defaultOrbitDistance = 60.0f;
float m_maxOrbitDistance = 100.0f;
} m_props;
};
@@ -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(),
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -365,10 +365,6 @@ bool CPreviewModelCtrl::Render()
}
_smart_ptr<IMaterial> pMaterial;
if (m_pCurrentMaterial)
{
pMaterial = m_pCurrentMaterial->GetMatInfo();
}
if (m_bPrecacheMaterial)
{
@@ -430,11 +426,6 @@ bool CPreviewModelCtrl::Render()
m_pRenderer->EF_ADDDlight(&m_lights[i], passInfo);
}
if (m_pCurrentMaterial)
{
m_pCurrentMaterial->DisableHighlightForFrame();
}
if (m_bShowObject)
{
RenderObject(pMaterial, passInfo);
@@ -778,32 +769,6 @@ void CPreviewModelCtrl::SetRotation(bool bEnable)
m_bRotate = bEnable;
}
void CPreviewModelCtrl::SetMaterial(CMaterial* pMaterial)
{
if (pMaterial)
{
if ((pMaterial->GetFlags() & MTL_FLAG_NOPREVIEW))
{
m_pCurrentMaterial = 0;
if (isVisible())
{
update();
}
return;
}
}
m_pCurrentMaterial = pMaterial;
if (isVisible())
{
update();
}
}
CMaterial* CPreviewModelCtrl::GetMaterial()
{
return m_pCurrentMaterial;
}
void CPreviewModelCtrl::OnEditorNotifyEvent(EEditorNotifyEvent event)
{
switch (event)
@@ -22,8 +22,6 @@
#include <IStatObj.h>
#include <Editor/Material/Material.h>
#endif
struct IRenderNode;
@@ -71,9 +69,6 @@ public:
int heightForWidth(int w) const override;
bool hasHeightForWidth() const override;
void SetMaterial(CMaterial* pMaterial);
CMaterial* GetMaterial();
void GetImageOffscreen(CImageEx& image, const QSize& customSize = QSize(0, 0));
void GetCameraTM(Matrix34& cameraTM);
@@ -192,7 +187,6 @@ protected:
float m_tileY;
float m_tileSizeX;
float m_tileSizeY;
_smart_ptr<CMaterial> m_pCurrentMaterial;
CameraChangeCallback m_cameraChangeCallback;
void* m_pCameraChangeUserData;
@@ -29,7 +29,6 @@ void RegisterReflectedVarHandlers()
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew AnimationPropertyWidgetHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew FileResourceSelectorWidgetHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew ShaderPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew MaterialPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew ReverbPresetPropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequencePropertyHandler());
EBUS_EVENT(AzToolsFramework::PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SequenceIdPropertyHandler());
@@ -27,7 +27,6 @@
// Editor
#include "ShadersDialog.h"
#include "Material/MaterialManager.h"
#include "SelectLightAnimationDialog.h"
#include "SelectSequenceDialog.h"
#include "SelectEAXPresetDlg.h"
@@ -88,25 +87,6 @@ void ShaderPropertyEditor::onEditClicked()
}
}
void MaterialPropertyEditor::onEditClicked()
{
}
void MaterialPropertyEditor::onButton2Clicked()
{
// Open material browser dialog.
IDataBaseItem *pItem = GetIEditor()->GetMaterialManager()->GetSelectedItem();
if (pItem)
{
QString value = pItem->GetName();
value.replace('\\', '/');
if (value.length() >= MAX_PATH)
value = value.left(MAX_PATH);
SetValue(value);
}
else
SetValue(QString());
}
void ReverbPresetPropertyEditor::onEditClicked()
{
@@ -109,16 +109,6 @@ public:
void onEditClicked() override;
};
class MaterialPropertyEditor
: public GenericPopupPropertyEditor
{
public:
MaterialPropertyEditor(QWidget* pParent = nullptr)
: GenericPopupPropertyEditor(pParent, true){}
void onEditClicked() override;
void onButton2Clicked() override;
};
class ReverbPresetPropertyEditor
: public GenericPopupPropertyEditor
{
@@ -179,7 +169,6 @@ public:
#define CONST_AZ_CRC(name, value) AZ::u32(value)
using ShaderPropertyHandler = GenericPopupWidgetHandler<ShaderPropertyEditor, CONST_AZ_CRC("ePropertyShader", 0xc40932f1)>;
using MaterialPropertyHandler = GenericPopupWidgetHandler<MaterialPropertyEditor, CONST_AZ_CRC("ePropertyMaterial", 0xf324dffa)>;
using ReverbPresetPropertyHandler = GenericPopupWidgetHandler<ReverbPresetPropertyEditor, CONST_AZ_CRC("ePropertyReverbPreset", 0x51469f38)>;
using MissionObjPropertyHandler = GenericPopupWidgetHandler<MissionObjPropertyEditor, CONST_AZ_CRC("ePropertyMissionObj", 0x4a2d0dc8)>;
using SequencePropertyHandler = GenericPopupWidgetHandler<SequencePropertyEditor, CONST_AZ_CRC("ePropertySequence", 0xdd1c7d44)>;
@@ -111,14 +111,12 @@ private:
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
newPath.replace("\\\\", "/");
}
switch (m_propertyType)
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
case ePropertyFile:
if (newPath.size() > MAX_PATH)
{
@@ -361,16 +361,6 @@ void ReflectedPropertyControl::CreateItems(XmlNodeRef node, CVarBlockPtr& outBlo
textureVar->Set(textureName);
}
}
else if (!azstricmp(type, "material"))
{
CSmartVariable<QString> materialVar;
AddVariable(group, materialVar, child->getTag(), humanReadableName.toUtf8().data(), strDescription.toUtf8().data(), func, pUserData, IVariable::DT_MATERIAL);
const char* materialName;
if (child->getAttr("value", &materialName))
{
materialVar->Set(materialName);
}
}
else if (!azstricmp(type, "color"))
{
CSmartVariable<Vec3> colorVar;
@@ -269,7 +269,6 @@ void ReflectedPropertyItem::SetVariable(IVariable *var)
m_reflectedVarAdapter = new ReflectedVarUserAdapter;
break;
case ePropertyShader:
case ePropertyMaterial:
case ePropertyEquip:
case ePropertyReverbPreset:
case ePropertyGameToken:
@@ -576,7 +575,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
value.replace('\\', '/');
break;
}
@@ -586,7 +584,6 @@ void ReflectedPropertyItem::SetValue(const QString& sValue, bool bRecordUndo, bo
{
case ePropertyTexture:
case ePropertyModel:
case ePropertyMaterial:
case ePropertyFile:
if (value.length() >= MAX_PATH)
{
@@ -286,8 +286,6 @@ AZ::u32 CReflectedVarGenericProperty::handler()
{
case ePropertyShader:
return AZ_CRC("ePropertyShader", 0xc40932f1);
case ePropertyMaterial:
return AZ_CRC("ePropertyMaterial", 0xf324dffa);
case ePropertyEquip:
return AZ_CRC("ePropertyEquip", 0x66ffd290);
case ePropertyReverbPreset:
@@ -455,8 +455,6 @@ void ReflectedVarGenericPropertyAdapter::SyncReflectedVarToIVar(IVariable *pVari
{
QString value;
pVariable->Get(value);
if (m_reflectedVar->m_propertyType == ePropertyMaterial)
value.replace('\\', '/');
m_reflectedVar->m_value = value.toUtf8().data();
}
-26
View File
@@ -102,7 +102,6 @@ AZ_POP_DISABLE_WARNING
#include "ModelViewport.h"
#include "FileTypeUtils.h"
#include "PluginManager.h"
#include "Material/MaterialManager.h"
#include "IEditorImpl.h"
#include "StartupLogoDialog.h"
@@ -157,9 +156,6 @@ AZ_POP_DISABLE_WARNING
#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h"
// LmbrCentral
#include <LmbrCentral/Rendering/MeshComponentBus.h>
// AWSNativeSDK
#include <AzToolsFramework/Undo/UndoSystem.h>
#include <AWSNativeSDKInit/AWSNativeSDKInit.h>
@@ -459,9 +455,6 @@ void CCryEditApp::RegisterActionHandlers()
ON_COMMAND(ID_CHANGEMOVESPEED_INCREASE, OnChangemovespeedIncrease)
ON_COMMAND(ID_CHANGEMOVESPEED_DECREASE, OnChangemovespeedDecrease)
ON_COMMAND(ID_CHANGEMOVESPEED_CHANGESTEP, OnChangemovespeedChangestep)
ON_COMMAND(ID_MATERIAL_ASSIGNCURRENT, OnMaterialAssigncurrent)
ON_COMMAND(ID_MATERIAL_RESETTODEFAULT, OnMaterialResettodefault)
ON_COMMAND(ID_MATERIAL_GETMATERIAL, OnMaterialGetmaterial)
ON_COMMAND(ID_FILE_SAVELEVELRESOURCES, OnFileSavelevelresources)
ON_COMMAND(ID_CLEAR_REGISTRY, OnClearRegistryData)
ON_COMMAND(ID_VALIDATELEVEL, OnValidatelevel)
@@ -4180,25 +4173,6 @@ void CCryEditApp::OnSwitchcameraNext()
}
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialAssigncurrent()
{
CUndo undo("Assign Material To Selection");
GetIEditor()->GetMaterialManager()->Command_AssignToSelection();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialResettodefault()
{
GetIEditor()->GetMaterialManager()->Command_ResetSelection();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnMaterialGetmaterial()
{
GetIEditor()->GetMaterialManager()->Command_SelectFromObject();
}
//////////////////////////////////////////////////////////////////////////
void CCryEditApp::OnOpenAssetBrowserView()
{
-3
View File
@@ -417,9 +417,6 @@ private:
void OnChangemovespeedIncrease();
void OnChangemovespeedDecrease();
void OnChangemovespeedChangestep();
void OnMaterialAssigncurrent();
void OnMaterialResettodefault();
void OnMaterialGetmaterial();
void OnFileSavelevelresources();
void OnClearRegistryData();
void OnValidatelevel();
+10 -13
View File
@@ -50,7 +50,6 @@
#include "CryEdit.h"
#include "ActionManager.h"
#include "Include/IObjectManager.h"
#include "Material/MaterialManager.h"
#include "ErrorReportDialog.h"
#include "SurfaceTypeValidator.h"
#include "ShaderCache.h"
@@ -356,8 +355,6 @@ void CCryEditDoc::Save(TDocMultiArchive& arrXmlAr)
SerializeFogSettings((*arrXmlAr[DMAS_GENERAL]));
// Serialize Missions //////////////////////////////////////////////////
SerializeMissions(arrXmlAr, currentMissionName, false);
//! Serialize material manager.
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
SerializeShaderCache((*arrXmlAr[DMAS_GENERAL_NAMED_DATA]));
SerializeNameSelection((*arrXmlAr[DMAS_GENERAL]));
@@ -512,14 +509,6 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
//////////////////////////////////////////////////////////////////////////
(*arrXmlAr[DMAS_GENERAL]).root->getAttr("WaterColor", m_waterColor);
//////////////////////////////////////////////////////////////////////////
// Load materials.
//////////////////////////////////////////////////////////////////////////
{
CAutoLogTime logtime("Load MaterialManager");
GetIEditor()->GetMaterialManager()->Serialize((*arrXmlAr[DMAS_GENERAL]).root, (*arrXmlAr[DMAS_GENERAL]).bLoading);
}
//////////////////////////////////////////////////////////////////////////
// Load View Settings
//////////////////////////////////////////////////////////////////////////
@@ -657,13 +646,21 @@ void CCryEditDoc::SerializeViewSettings(CXmlArchive& xmlAr)
CViewport* pVP = GetIEditor()->GetViewManager()->GetView(i);
Matrix34 tm = Matrix34::CreateRotationXYZ(va);
tm.SetTranslation(vp);
if (pVP)
{
Matrix34 tm = Matrix34::CreateRotationXYZ(va);
tm.SetTranslation(vp);
pVP->SetViewTM(tm);
}
if (auto viewportContext = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get()->GetDefaultViewportContext())
{
AzFramework::ModernViewportCameraControllerRequestBus::Event(
viewportContext->GetId(), &AzFramework::ModernViewportCameraControllerRequestBus::Events::SetTargetCameraTransform,
LYTransformToAZTransform(tm));
}
// Load grid.
auto gridName = QString("Grid%1").arg(useOldViewFormat ? "" : QString::number(i));
XmlNodeRef gridNode = xmlAr.root->newChild(gridName.toUtf8().constData());
-25
View File
@@ -22,7 +22,6 @@
// Editor
#include "Settings.h"
#include "Material/MaterialManager.h"
@@ -112,30 +111,6 @@ void CDisplaySettings::SetDebugFlags(int flags)
//SetCVarInt( "sys_enable_budgetmonitoring",(m_debugFlags&DBG_BUDGET_MONITORING) ? 4:0 );
//SetCVarInt( "Profile",(m_debugFlags&DBG_FRAMEPROFILE) ? 1:0 );
if (CMaterialManager* pMaterialManager = GetIEditor()->GetMaterialManager())
{
int mask = pMaterialManager->GetHighlightMask();
if (m_debugFlags & DBG_HIGHLIGHT_BREAKABLE)
{
mask |= eHighlight_Breakable;
}
else
{
mask &= ~eHighlight_Breakable;
}
if (m_debugFlags & DBG_HIGHLIGHT_MISSING_SURFACE_TYPE)
{
mask |= eHighlight_NoSurfaceType;
}
else
{
mask &= ~eHighlight_NoSurfaceType;
}
pMaterialManager->SetHighlightMask(mask);
}
}
//////////////////////////////////////////////////////////////////////////
@@ -21,14 +21,12 @@
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
#include <AzToolsFramework/Thumbnails/ThumbnailerComponent.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserComponent.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h>
// Editor
#include "MainWindow.h"
#include "CryEdit.h"
#include "DisplaySettingsPythonFuncs.h"
#include "GameEngine.h"
#include "Material/MaterialPythonFuncs.h"
#include "PythonEditorFuncs.h"
#include "TrackView/TrackViewPythonFuncs.h"
#include "Include/IObjectManager.h"
@@ -65,7 +63,6 @@ namespace EditorInternal
RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsPythonFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::MainWindowEditorFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::ObjectManagerFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::MaterialPythonFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::PythonEditorComponent::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::PythonEditorFuncsHandler::CreateDescriptor());
RegisterComponentDescriptor(AzToolsFramework::DisplaySettingsComponent::CreateDescriptor());
@@ -81,7 +78,6 @@ namespace EditorInternal
components.emplace_back(azrtti_typeid<AzToolsFramework::Thumbnailer::ThumbnailerComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::AssetBrowser::AssetBrowserComponent>());
components.emplace_back(azrtti_typeid<AzToolsFramework::MaterialBrowser::MaterialBrowserComponent>());
// Add new Bus-based Python Bindings
components.emplace_back(azrtti_typeid<AzToolsFramework::DisplaySettingsComponent>());
+2 -2
View File
@@ -1625,8 +1625,8 @@ void EditorViewportWidget::keyPressEvent(QKeyEvent* event)
QCoreApplication::sendEvent(GetIEditor()->GetEditorMainWindow(), event);
}
// NOTE: we keep track of keypresses and releases explicitly because the OS/Qt will insert a slight delay between sending
// keyevents when the key is held down. This is standard, but makes responding to key events for game style input silly
// NOTE: we keep track of key presses and releases explicitly because the OS/Qt will insert a slight delay between sending
// key events when the key is held down. This is standard, but makes responding to key events for game style input silly
// because we want the movement to be butter smooth.
if (!event->isAutoRepeat())
{
-1
View File
@@ -19,7 +19,6 @@
#pragma once
// forward declarations.
class CMaterial;
class CParticleItem;
#include "BaseLibraryItem.h"
@@ -23,7 +23,6 @@
// Editor
#include "Geometry/EdGeometry.h"
#include "Material/Material.h"
#include "ViewManager.h"
#include "OBJExporter.h"
#include "OCMExporter.h"
@@ -79,47 +78,6 @@ Export::CMesh::CMesh()
}
void Export::CMesh::SetMaterial(CMaterial* pMtl, CBaseObject* pBaseObj)
{
if (!pMtl)
{
cry_strcpy(material.name, pBaseObj->GetName().toUtf8().data());
return;
}
cry_strcpy(material.name, pMtl->GetFullName().toUtf8().data());
_smart_ptr<IMaterial> matInfo = pMtl->GetMatInfo();
IRenderShaderResources* pRes = matInfo->GetShaderItem().m_pShaderResources;
if (!pRes)
{
return;
}
ColorF difColor = pRes->GetColorValue(EFTT_DIFFUSE);
material.diffuse.r = difColor.r;
material.diffuse.g = difColor.g;
material.diffuse.b = difColor.b;
material.diffuse.a = difColor.a;
ColorF specColor = pRes->GetColorValue(EFTT_SPECULAR);
material.specular.r = specColor.r;
material.specular.g = specColor.g;
material.specular.b = specColor.b;
material.specular.a = specColor.a;
material.opacity = pRes->GetStrengthValue(EFTT_OPACITY);
material.smoothness = pRes->GetStrengthValue(EFTT_SMOOTHNESS);
SetTexture(material.mapDiffuse, pRes, EFTT_DIFFUSE);
SetTexture(material.mapSpecular, pRes, EFTT_SPECULAR);
SetTexture(material.mapOpacity, pRes, EFTT_OPACITY);
SetTexture(material.mapNormals, pRes, EFTT_NORMALS);
SetTexture(material.mapDecal, pRes, EFTT_DECAL_OVERLAY);
SetTexture(material.mapDisplacement, pRes, EFTT_HEIGHT);
}
//////////////////////////////////////////////////////////
// CObject
Export::CObject::CObject(const char* pName)
@@ -416,18 +374,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
pObj->m_texCoords.push_back(tc);
}
CMaterial* pMtl = 0;
if (m_pBaseObj)
{
pMtl = m_pBaseObj->GetRenderMaterial();
}
if (pMtl)
{
pObj->SetMaterialName(pMtl->GetFullName().toUtf8().data());
}
if (pIndMesh->GetSubSetCount() && !(pIndMesh->GetSubSetCount() == 1 && pIndMesh->GetSubSet(0).nNumIndices == 0))
{
for (int i = 0; i < pIndMesh->GetSubSetCount(); ++i)
@@ -447,23 +393,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
pMesh->m_faces.push_back(face);
}
if (pMtl)
{
if (pMtl->IsMultiSubMaterial())
{
CMaterial* pSubMtl = 0;
if (sms.nMatID < pMtl->GetSubMaterialCount())
{
pSubMtl = pMtl->GetSubMaterial(sms.nMatID);
}
pMesh->SetMaterial(pSubMtl, m_pBaseObj);
}
else
{
pMesh->SetMaterial(pMtl, m_pBaseObj);
}
}
pObj->m_meshes.push_back(pMesh);
}
}
@@ -497,10 +426,6 @@ void CExportManager::AddMesh(Export::CObject* pObj, const IIndexedMesh* pIndMesh
}
}
if (m_pBaseObj && pMtl)
{
pMesh->SetMaterial(pMtl, m_pBaseObj);
}
pObj->m_meshes.push_back(pMesh);
}
}
@@ -43,8 +43,6 @@ namespace Export
virtual int GetFaceCount() const { return m_faces.size(); }
virtual const Face* GetFaceBuffer() const { return m_faces.size() ? &m_faces[0] : 0; }
void SetMaterial(CMaterial* pMtl, CBaseObject* pBaseObj);
private:
std::vector<Face> m_faces;
-49
View File
@@ -27,8 +27,6 @@
#include "Mission.h"
#include "ShaderCache.h"
#include "UsedResources.h"
#include "Material/MaterialManager.h"
#include "Material/MaterialLibrary.h"
#include "WaitProgress.h"
#include "Util/CryMemFile.h"
#include "Objects/ObjectManager.h"
@@ -336,11 +334,6 @@ void CGameExporter::ExportLevelData(const QString& path, bool bExportMission)
ExportMapInfo(root);
//////////////////////////////////////////////////////////////////////////
// Export materials.
ExportMaterials(root, path);
//////////////////////////////////////////////////////////////////////////
CCryEditDoc* pDocument = pEditor->GetDocument();
CMission* pCurrentMission = 0;
@@ -508,48 +501,6 @@ void CGameExporter::ExportMapInfo(XmlNodeRef& node)
xmlAr.root = node;
}
//////////////////////////////////////////////////////////////////////////
void CGameExporter::ExportMaterials(XmlNodeRef& levelDataNode, const QString& path)
{
//////////////////////////////////////////////////////////////////////////
// Export materials manager.
CMaterialManager* pManager = GetIEditor()->GetMaterialManager();
pManager->Export(levelDataNode);
QString filename = Path::Make(path, MATERIAL_LEVEL_LIBRARY_FILE);
bool bHaveItems = true;
int numMtls = 0;
XmlNodeRef nodeMaterials = XmlHelpers::CreateXmlNode("MaterialsLibrary");
// Export Materials local level library.
for (int i = 0; i < pManager->GetLibraryCount(); i++)
{
XmlNodeRef nodeLib = nodeMaterials->newChild("Library");
CMaterialLibrary* pLib = (CMaterialLibrary*)pManager->GetLibrary(i);
if (pLib->GetItemCount() > 0)
{
bHaveItems = false;
// Export this library.
numMtls += pManager->ExportLib(pLib, nodeLib);
}
}
if (!bHaveItems)
{
XmlString xmlData = nodeMaterials->getXML();
CCryMemFile file;
file.Write(xmlData.c_str(), xmlData.length());
m_levelPak.m_pakFile.UpdateFile(filename.toUtf8().data(), file);
}
else
{
m_levelPak.m_pakFile.RemoveFile(filename.toUtf8().data());
}
m_numExportedMaterials = numMtls;
}
//////////////////////////////////////////////////////////////////////////
void CGameExporter::ExportLevelResourceList(const QString& path)
{
-1
View File
@@ -98,7 +98,6 @@ private:
void ExportLevelResourceList(const QString& path);
void ExportLevelUsedResourceList(const QString& path);
void ExportLevelShaderCache(const QString& path);
void ExportMaterials(XmlNodeRef& levelDataNode, const QString& path);
void ExportGameData(const QString& path);
void ExportFileList(const QString& path, const QString& levelName);
+1 -12
View File
@@ -21,7 +21,6 @@
// Editor
#include "UsedResources.h"
#include "GameEngine.h"
#include "Material/MaterialManager.h"
#include "Include/IObjectManager.h"
#include "WaitProgress.h"
@@ -51,7 +50,7 @@ void CGameResourcesExporter::ChooseDirectory()
void CGameResourcesExporter::GatherAllLoadedResources()
{
m_files.clear();
m_files.reserve(100000); // count from GetResourceList, GetFilesFromObjects, GetFilesFromMaterials ... is unknown
m_files.reserve(100000); // count from GetResourceList, GetFilesFromObjects ... is unknown
auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level);
{
@@ -62,7 +61,6 @@ void CGameResourcesExporter::GatherAllLoadedResources()
}
GetFilesFromObjects();
GetFilesFromMaterials();
}
//////////////////////////////////////////////////////////////////////////
@@ -158,12 +156,3 @@ void CGameResourcesExporter::GetFilesFromObjects()
Append(m_files, rs.files);
}
//////////////////////////////////////////////////////////////////////////
void CGameResourcesExporter::GetFilesFromMaterials()
{
CUsedResources rs;
GetIEditor()->GetMaterialManager()->GatherUsedResources(rs);
Append(m_files, rs.files);
}
@@ -44,7 +44,6 @@ private:
void GetFilesFromObjects();
void GetFilesFromVarBlock(CVarBlock* pVB);
void GetFilesFromVariable(IVariable* pVar);
void GetFilesFromMaterials();
};
#endif // CRYINCLUDE_EDITOR_GAMERESOURCESEXPORTER_H
-4
View File
@@ -46,9 +46,7 @@ class CGameEngine;
struct IIconManager;
class CToolBoxManager;
class CClassFactory;
class CMaterialManager;
class CMusicManager;
class CMaterail;
struct IEditorParticleManager;
class CEAXPresetManager;
class CErrorReport;
@@ -544,8 +542,6 @@ struct IEditor
virtual CSettingsManager* GetSettingsManager() = 0;
//! Get DB manager that own items of specified type.
virtual IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType) = 0;
//! Get Manager of Materials.
virtual CMaterialManager* GetMaterialManager() = 0;
virtual IBaseLibraryManager* GetMaterialManagerLibrary() = 0; // Vladimir@conffx
virtual IEditorMaterialManager* GetIEditorMaterialManager() = 0; // Vladimir@Conffx
//! Returns IconManager.
+3 -13
View File
@@ -53,7 +53,6 @@ AZ_POP_DISABLE_WARNING
#include "KeyboardCustomizationSettings.h"
#include "Export/ExportManager.h"
#include "LevelIndependentFileMan.h"
#include "Material/MaterialManager.h"
#include "TrackView/TrackViewSequenceManager.h"
#include "AnimationContext.h"
#include "GameEngine.h"
@@ -167,7 +166,6 @@ CEditorImpl::CEditorImpl()
, m_pAnimationContext(nullptr)
, m_pSequenceManager(nullptr)
, m_pToolBoxManager(nullptr)
, m_pMaterialManager(nullptr)
, m_pMusicManager(nullptr)
, m_pErrorReport(nullptr)
, m_pLasLoadedLevelErrorReport(nullptr)
@@ -222,7 +220,6 @@ CEditorImpl::CEditorImpl()
m_pIconManager = new CIconManager;
m_pUndoManager = new CUndoManager;
m_pToolBoxManager = new CToolBoxManager;
m_pMaterialManager = new CMaterialManager(regCtx);
m_pAlembicCompiler = new CAlembicCompiler();
m_pSequenceManager = new CTrackViewSequenceManager;
m_pAnimationContext = new CAnimationContext;
@@ -342,7 +339,6 @@ CEditorImpl::~CEditorImpl()
m_bExiting = true; // Can't save level after this point (while Crash)
SAFE_RELEASE(m_pSourceControl);
SAFE_DELETE(m_pMaterialManager)
SAFE_DELETE(m_pAlembicCompiler)
SAFE_DELETE(m_pIconManager)
SAFE_DELETE(m_pViewManager)
@@ -412,7 +408,6 @@ void CEditorImpl::SetGameEngine(CGameEngine* ge)
m_pObjectManager->LoadClassTemplates("Editor");
m_pObjectManager->RegisterCVars();
m_pMaterialManager->Set3DEngine();
m_pAnimationContext->Init();
}
@@ -1000,13 +995,8 @@ void CEditorImpl::CloseView(const GUID& classId)
}
}
IDataBaseManager* CEditorImpl::GetDBItemManager(EDataBaseItemType itemType)
IDataBaseManager* CEditorImpl::GetDBItemManager([[maybe_unused]] EDataBaseItemType itemType)
{
switch (itemType)
{
case EDB_TYPE_MATERIAL:
return m_pMaterialManager;
}
return 0;
}
@@ -1772,13 +1762,13 @@ SEditorSettings* CEditorImpl::GetEditorSettings()
// Vladimir@Conffx
IBaseLibraryManager* CEditorImpl::GetMaterialManagerLibrary()
{
return m_pMaterialManager;
return nullptr;
}
// Vladimir@Conffx
IEditorMaterialManager* CEditorImpl::GetIEditorMaterialManager()
{
return m_pMaterialManager;
return nullptr;
}
IImageUtil* CEditorImpl::GetImageUtil()
-2
View File
@@ -180,7 +180,6 @@ public:
bool IsSelectionLocked();
IDataBaseManager* GetDBItemManager(EDataBaseItemType itemType);
CMaterialManager* GetMaterialManager() { return m_pMaterialManager; }
CMusicManager* GetMusicManager() { return m_pMusicManager; };
IBackgroundTaskManager* GetBackgroundTaskManager() override;
@@ -379,7 +378,6 @@ protected:
CAnimationContext* m_pAnimationContext;
CTrackViewSequenceManager* m_pSequenceManager;
CToolBoxManager* m_pToolBoxManager;
CMaterialManager* m_pMaterialManager;
CAlembicCompiler* m_pAlembicCompiler;
CMusicManager* m_pMusicManager;
CErrorReport* m_pErrorReport;
@@ -21,7 +21,6 @@
#include <IValidator.h>
// forward declarations.
class CMaterial;
class CParticleItem;
class CBaseObject;
class CBaseLibraryItem;
-10
View File
@@ -20,7 +20,6 @@
// Editor
#include "Util/fastlib.h"
#include "Material/MaterialManager.h" // for CMaterialManager
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
@@ -67,7 +66,6 @@ void CLevelInfo::Validate()
// Validate level.
ValidateObjects();
ValidateMaterials();
if (m_pReport->GetErrorCount() == 0)
{
@@ -186,11 +184,3 @@ void CLevelInfo::ValidateObjects()
}
}
}
//////////////////////////////////////////////////////////////////////////
void CLevelInfo::ValidateMaterials()
{
// Validate all objects
CBaseObjectsArray objects;
GetIEditor()->GetMaterialManager()->Validate();
}
-1
View File
@@ -27,7 +27,6 @@ public:
private:
void ValidateObjects();
void ValidateMaterials();
IErrorReport* m_pReport;
};
@@ -91,7 +91,6 @@ public:
MOCK_METHOD0(GetObjectManager, struct IObjectManager* ());
MOCK_METHOD0(GetSettingsManager, CSettingsManager* ());
MOCK_METHOD1(GetDBItemManager, IDataBaseManager* (EDataBaseItemType));
MOCK_METHOD0(GetMaterialManager, CMaterialManager* ());
MOCK_METHOD0(GetMaterialManagerLibrary, IBaseLibraryManager* ());
MOCK_METHOD0(GetIEditorMaterialManager, IEditorMaterialManager* ());
MOCK_METHOD0(GetIconManager, IIconManager* ());
@@ -1,68 +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 "EditorDefs.h"
#include <AzTest/AzTest.h>
#include <Util/EditorUtils.h>
#include <AzCore/base.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzToolsFramework/Application/ToolsApplication.h>
#include <Material/MaterialPythonFuncs.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace MaterialPythonFuncsUnitTests
{
class MaterialPythonBindingsFixture
: public testing::Test
{
public:
AzToolsFramework::ToolsApplication m_app;
void SetUp() override
{
AzFramework::Application::Descriptor appDesc;
appDesc.m_enableDrilling = false;
m_app.Start(appDesc);
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
// in the unit tests.
AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
m_app.RegisterComponentDescriptor(AzToolsFramework::MaterialPythonFuncsHandler::CreateDescriptor());
}
void TearDown() override
{
m_app.Stop();
}
};
TEST_F(MaterialPythonBindingsFixture, MaterialEditorCommands_ApiExists)
{
AZ::BehaviorContext* behaviorContext = m_app.GetBehaviorContext();
ASSERT_TRUE(behaviorContext);
EXPECT_TRUE(behaviorContext->m_methods.find("create") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("create_multi") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("convert_to_multi") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("duplicate_current") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("merge_selection") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("delete_current") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("get_submaterial") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("get_property") != behaviorContext->m_methods.end());
EXPECT_TRUE(behaviorContext->m_methods.find("set_property") != behaviorContext->m_methods.end());
}
}
-2
View File
@@ -93,13 +93,11 @@ AZ_POP_DISABLE_WARNING
#include "TimeOfDayDialog.h"
#include "Dialogs/PythonScriptsDialog.h"
#include "Material/MaterialManager.h"
#include "EngineSettingsManager.h"
#include "AzAssetBrowser/AzAssetBrowserWindow.h"
#include "AssetEditor/AssetEditorWindow.h"
#include "GridSettingsDialog.h"
#include "MaterialSender.h"
#include "ActionManager.h"
// uncomment this to show thumbnail demo widget
-149
View File
@@ -1,149 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "MatEditPreviewDlg.h"
// Qt
#include <QFileDialog>
#include <QMenuBar>
#include <QVBoxLayout>
// Editor
#include "Material/MaterialManager.h"
#include "Material/MaterialPreviewModelView.h"
/////////////////////////////////////////////////////////////////////////////
// CMatEditPreviewDlg dialog
CMatEditPreviewDlg::CMatEditPreviewDlg(QWidget* parent)
: QDialog(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setWindowTitle(tr("Material Preview"));
/* create sub controls */
m_previewCtrl.reset(new MaterialPreviewModelView(this));
m_menubar.reset(new QMenuBar);
/* configure layout */
QVBoxLayout* layout = new QVBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_menubar.data());
layout->addWidget(m_previewCtrl.data());
layout->setStretchFactor(m_previewCtrl.data(), 1);
setLayout(layout);
GetIEditor()->GetMaterialManager()->AddListener(this);
SetupMenuBar();
OnPreviewPlane();
m_previewCtrl->SetMaterial(GetIEditor()->GetMaterialManager()->GetCurrentMaterial() ? GetIEditor()->GetMaterialManager()->GetCurrentMaterial()->GetMatInfo() : nullptr);
m_previewCtrl->Update();
}
CMatEditPreviewDlg::~CMatEditPreviewDlg()
{
GetIEditor()->GetMaterialManager()->RemoveListener(this);
}
QSize CMatEditPreviewDlg::sizeHint() const
{
return QSize(450, 400);
}
void CMatEditPreviewDlg::showEvent(QShowEvent* e)
{
QDialog::showEvent(e);
resize(sizeHint()); // Because WindowDecorationWrapper resizes it to the minimum for some reason.
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::SetupMenuBar()
{
QMenu* menu;
QAction* action;
menu = m_menubar->addMenu(tr("Preview"));
action = menu->addAction(tr("&Plane"));
connect(action, &QAction::triggered, this, &CMatEditPreviewDlg::OnPreviewPlane);
action = menu->addAction(tr("&Sphere"));
connect(action, &QAction::triggered, this, &CMatEditPreviewDlg::OnPreviewSphere);
action = menu->addAction(tr("&Box"));
connect(action, &QAction::triggered, this, &CMatEditPreviewDlg::OnPreviewBox);
action = menu->addAction(tr("&Teapot"));
connect(action, &QAction::triggered, this, &CMatEditPreviewDlg::OnPreviewTeapot);
action = menu->addAction(tr("&Custom"));
connect(action, &QAction::triggered, this, &CMatEditPreviewDlg::OnPreviewCustom);
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::OnPreviewSphere()
{
m_previewCtrl->LoadModelFile("Objects/MtlSphere.cgf");
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::OnPreviewBox()
{
m_previewCtrl->LoadModelFile("Objects/MtlBox.cgf");
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::OnPreviewTeapot()
{
m_previewCtrl->LoadModelFile("Objects/MtlTeapot.cgf");
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::OnPreviewPlane()
{
m_previewCtrl->LoadModelFile("Objects/MtlPlane.cgf");
}
//////////////////////////////////////////////////////////////////////////
void CMatEditPreviewDlg::OnPreviewCustom()
{
const QString fullFileName =
QFileDialog::getOpenFileName(this, tr("Custom Model"), QString(), tr("Objects (*.cgf);;All files (*.*)"));
if (!fullFileName.isNull())
{
m_previewCtrl->LoadModelFile(fullFileName);
}
}
/////////////////////////////////////////////////////////////////////////////
// CMatEditPreviewDlg message handlers
void CMatEditPreviewDlg::OnDataBaseItemEvent([[maybe_unused]] IDataBaseItem* pItem, EDataBaseItemEvent event)
{
switch (event)
{
case EDB_ITEM_EVENT_SELECTED:
case EDB_ITEM_EVENT_ADD:
case EDB_ITEM_EVENT_CHANGED:
m_previewCtrl->SetMaterial(GetIEditor()->GetMaterialManager()->GetCurrentMaterial() ? GetIEditor()->GetMaterialManager()->GetCurrentMaterial()->GetMatInfo() : nullptr);
break;
case EDB_ITEM_EVENT_DELETE:
m_previewCtrl->SetMaterial(nullptr);
break;
}
}
#include <moc_MatEditPreviewDlg.cpp>
-66
View File
@@ -1,66 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATEDITPREVIEWDLG_H
#define CRYINCLUDE_EDITOR_MATEDITPREVIEWDLG_H
#pragma once
#if !defined(Q_MOC_RUN)
#include <QDialog>
#include <QScopedPointer>
#include "IDataBaseManager.h"
#endif
class MaterialPreviewModelView;
class QMenuBar;
// MatEditPreviewDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMatEditPreviewDlg dialog
class CMatEditPreviewDlg
: public QDialog
, public IDataBaseManagerListener
{
Q_OBJECT
// Construction
public:
CMatEditPreviewDlg(QWidget* parent); // standard constructor
~CMatEditPreviewDlg();
QSize sizeHint() const override;
void showEvent(QShowEvent*) override;
//Functions
virtual void OnDataBaseItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event);
protected:
void SetupMenuBar();
private slots:
void OnPreviewSphere();
void OnPreviewPlane();
void OnPreviewBox();
void OnPreviewTeapot();
void OnPreviewCustom();
private:
QScopedPointer<MaterialPreviewModelView> m_previewCtrl;
QScopedPointer<QMenuBar> m_menubar;
};
#endif // CRYINCLUDE_EDITOR_MATEDITPREVIEWDLG_H
File diff suppressed because it is too large Load Diff
-315
View File
@@ -1,315 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIAL_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIAL_H
#pragma once
#include <IMaterial.h>
#include <IRenderer.h>
#include "BaseLibraryItem.h"
#include "Include/IEditorMaterial.h"
#include "Util/Variable.h"
#include <vector>
// forward declarations,
class CMaterialManager;
class CVarBlock;
enum eMTL_PROPAGATION
{
MTL_PROPAGATE_OPACITY = 1 << 0,
MTL_PROPAGATE_LIGHTING = 1 << 1,
MTL_PROPAGATE_ADVANCED = 1 << 2,
MTL_PROPAGATE_TEXTURES = 1 << 3,
MTL_PROPAGATE_SHADER_PARAMS = 1 << 4,
MTL_PROPAGATE_SHADER_GEN = 1 << 5,
MTL_PROPAGATE_VERTEX_DEF = 1 << 6,
MTL_PROPAGATE_LAYER_PRESETS = 1 << 7,
MTL_PROPAGATE_MATERIAL_SETTINGS = 1 << 8,
MTL_PROPAGATE_ALL = (
MTL_PROPAGATE_OPACITY |
MTL_PROPAGATE_LIGHTING |
MTL_PROPAGATE_ADVANCED |
MTL_PROPAGATE_TEXTURES |
MTL_PROPAGATE_SHADER_PARAMS |
MTL_PROPAGATE_SHADER_GEN |
MTL_PROPAGATE_VERTEX_DEF |
MTL_PROPAGATE_LAYER_PRESETS |
MTL_PROPAGATE_MATERIAL_SETTINGS),
MTL_PROPAGATE_RESERVED = 1 << 9
};
/** CMaterial class
Every Material is a member of material library.
Materials can have child sub materials,
Sub materials are applied to the same geometry of the parent material in the other material slots.
*/
struct SMaterialLayerResources
{
SMaterialLayerResources()
: m_nFlags(MTL_LAYER_USAGE_REPLACEBASE)
, m_bRegetPublicParams(true)
, m_pMatLayer(0)
{
}
uint8 m_nFlags;
bool m_bRegetPublicParams;
QString m_shaderName;
_smart_ptr< IMaterialLayer > m_pMatLayer;
SInputShaderResources m_shaderResources;
XmlNodeRef m_publicVarsCache;
};
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
class CRYEDIT_API CMaterial
: public IEditorMaterial
{
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
public:
//////////////////////////////////////////////////////////////////////////
CMaterial(const QString& name, int nFlags = 0);
CMaterial(const CMaterial& rhs);
~CMaterial();
virtual EDataBaseItemType GetType() const { return EDB_TYPE_MATERIAL; };
void SetName(const QString& name);
//////////////////////////////////////////////////////////////////////////
QString GetFullName() const { return m_name; };
//////////////////////////////////////////////////////////////////////////
// File properties of the material.
//////////////////////////////////////////////////////////////////////////
QString GetFilename() const;
//! Collect filenames of texture sources used in material
//! Return number of filenames
int GetTextureFilenames(QStringList& outFilenames) const;
int GetAnyTextureFilenames(QStringList& outFilenames) const;
void UpdateFileAttributes(bool useSourceControl = true);
uint32 GetFileAttributes();
//////////////////////////////////////////////////////////////////////////
//! Sets one or more material flags from EMaterialFlags enum.
void SetFlags(int flags) { m_mtlFlags = flags; };
//! Query this material flags.
virtual int GetFlags() const { return m_mtlFlags; }
bool IsMultiSubMaterial() const { return (m_mtlFlags & MTL_FLAG_MULTI_SUBMTL) != 0; };
bool IsPureChild() const { return (m_mtlFlags & MTL_FLAG_PURE_CHILD) != 0; }
// Check if material is used.
bool IsUsed() const { /*return m_nUseCount > 0 || (m_mtlFlags & MTL_FLAG_ALWAYS_USED);*/ return true; };
virtual void GatherUsedResources(CUsedResources& resources);
//! Set name of shader used by this material.
void SetShaderName(const QString& shaderName);
//! Get name of shader used by this material.
QString GetShaderName() const { return m_shaderName; };
virtual SInputShaderResources& GetShaderResources() { return m_shaderResources; };
//! Get public parameters of material in variable block.
CVarBlock* GetPublicVars(SInputShaderResources& pShaderResources);
//! Set the shader public param m_script variable into our own m_script, script contains min/max for a given shader param value
void SetShaderParamPublicScript();
//! Sets variable block of public shader parameters.
//! VarBlock must be in same format as returned by GetPublicVars().
void SetPublicVars(CVarBlock* pPublicVars, CMaterial* pMtl);
//! Update names/descriptions in this variable array, return a variable block for replacing
CVarBlock* UpdateTextureNames(CSmartVariableArray textureVars[EFTT_MAX]);
// [Shader System] - Do To: add back with map usage: CVarBlock* UpdateTextureNames(AZStd::unordered_map<ResourceSlotIndex, CSmartVariableArray>& textureVarsMap);
//////////////////////////////////////////////////////////////////////////
CVarBlock* GetShaderGenParamsVars();
void SetShaderGenParamsVars(CVarBlock* pBlock);
uint64 GetShaderGenMask() { return m_nShaderGenMask; }
void SetShaderGenMask(uint64 mask) { m_nShaderGenMask = mask; }
//! Return variable block of shader params.
SShaderItem& GetShaderItem() { return m_shaderItem; };
//! Return material layers resources
SMaterialLayerResources* GetMtlLayerResources() { return m_pMtlLayerResources; };
//! Get texture map usage mask for shader in this material.
unsigned int GetTexmapUsageMask() const;
//! Load new shader.
bool LoadShader();
//! Reload shader, update all shader parameters.
virtual void Update();
// Reload material settings from file.
// NOTICE: The function will remove all the sub-materials and recreate them!
void Reload();
//! Serialize material settings to xml.
virtual void Serialize(SerializeContext& ctx);
//! Assign this material to static geometry.
void AssignToEntity(IRenderNode* pEntity);
//////////////////////////////////////////////////////////////////////////
// Surface types.
//////////////////////////////////////////////////////////////////////////
virtual void SetSurfaceTypeName(const QString& surfaceType);
virtual const QString& GetSurfaceTypeName() const { return m_surfaceType; };
bool IsBreakable2D() const;
//////////////////////////////////////////////////////////////////////////
// Child Sub materials.
//////////////////////////////////////////////////////////////////////////
//! Get number of sub materials childs.
int GetSubMaterialCount() const;
//! Set number of sub materials childs.
void SetSubMaterialCount(int nSubMtlsCount);
//! Get sub material child by index.
CMaterial* GetSubMaterial(int index) const;
//! Find sub material index by name
int FindMaterialIndex(const QString& name);
// Set a material to the sub materials slot.
// Use NULL material pointer to clear slot.
void SetSubMaterial(int nSlot, CMaterial* mtl);
//! Remove all sub materials, does not change number of sub material slots.
void ClearAllSubMaterials();
//! Return pointer to engine material.
virtual _smart_ptr<IMaterial> GetMatInfo(bool bUseExistingEngineMaterial = true);
// Clear stored pointer to engine material.
void ClearMatInfo();
//! Validate materials for errors.
void Validate();
// Check if material file can be modified.
// Will check file attributes if it is not read only.
bool CanModify(bool bSkipReadOnly = true);
// Save material to file.
virtual bool Save(bool bSkipReadOnly = true, const QString& fullPath = "");
// Dummy material is just a placeholder item for materials that have not been found on disk.
void SetDummy(bool bDummy) { m_bDummyMaterial = bDummy; }
bool IsDummy() const { return m_bDummyMaterial != 0; }
// Called by material manager when material selected as a current material.
void OnMakeCurrent();
void SetFromMatInfo(_smart_ptr<IMaterial> pMatInfo);
// Link a submaterial by name (used for value propagation in CMaterialUI)
void LinkToMaterial(const QString& name);
const QString& GetLinkedMaterialName() { return m_linkedMaterial; }
// Return parent material for submaterial
CMaterial* GetParent() const {return m_pParent; }
//! Loads material layers
bool LoadMaterialLayers();
//! Updates material layers
void UpdateMaterialLayers();
void SetHighlightFlags(int highlightFlags);
void UpdateHighlighting();
virtual void DisableHighlightForFrame();
void RecordUndo(const char* sText, bool bForceUpdate = false);
int GetPropagationFlags() const { return m_propagationFlags; }
void SetPropagationFlags(const int flags) { m_propagationFlags = flags; }
bool LayerActivationAllowed() const { return m_allowLayerActivation; }
void SetLayerActivation(bool allowed) { m_allowLayerActivation = allowed; }
uint32 GetDccMaterialHash() const { return m_dccMaterialHash; }
void SetDccMaterialHash(AZ::u32 hash) { m_dccMaterialHash = hash; }
void SetShaderItem(const SShaderItem& shaderItem);
private:
void UpdateMatInfo();
void CheckSpecialConditions();
void NotifyChanged();
private:
//////////////////////////////////////////////////////////////////////////
// Variables.
//////////////////////////////////////////////////////////////////////////
QString m_shaderName;
QString m_surfaceType;
QString m_linkedMaterial;
//! Material flags.
int m_mtlFlags;
// Hash for DCC material attributes, used to check if .dccmtl has changed
// If so, the source .mtl file will need to be rebuilt
uint32 m_dccMaterialHash;
// Parent material, Only valid for Pure Childs.
CMaterial* m_pParent;
//////////////////////////////////////////////////////////////////////////
// Shader resources.
//////////////////////////////////////////////////////////////////////////
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
SShaderItem m_shaderItem;
SInputShaderResources m_shaderResources;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
//CVarBlockPtr m_shaderParamsVar;
//! Common shader flags.
uint64 m_nShaderGenMask;
QString m_pszShaderGenMask;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
SMaterialLayerResources m_pMtlLayerResources[MTL_LAYER_MAX_SLOTS];
_smart_ptr<IMaterial> m_pMatInfo;
XmlNodeRef m_publicVarsCache;
//! Array of sub materials.
std::vector<_smart_ptr<CMaterial> > m_subMaterials;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
int m_nUseCount;
uint32 m_scFileAttributes;
unsigned char m_highlightFlags;
// The propagation flags are a bit combination of the MTL_PROPAGATION enum above
// and determine which properties get propagated to an optional linked material
// during ui editing
int m_propagationFlags;
//! Material Used in level.
unsigned int m_bDummyMaterial : 1; // Dummy material, name specified but material file not found.
unsigned int m_bIgnoreNotifyChange : 1; // Do not send notifications about changes.
unsigned int m_bRegetPublicParams : 1;
unsigned int m_bKeepPublicParamsValues : 1;
bool m_allowLayerActivation;
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIAL_H
File diff suppressed because it is too large Load Diff
@@ -1,248 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALBROWSER_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIALBROWSER_H
#pragma once
#if !defined(Q_MOC_RUN)
#include "Include/IDataBaseManager.h"
#include "Material/Material.h"
#include "Material/MaterialBrowserFilterModel.h"
#include <QMenu>
#include <QDateTime>
#include <QModelIndex>
#include <ISourceControl.h>
#include <AzToolsFramework/AssetBrowser/Search/Filter.h>
#endif
class CMaterial;
class MaterialBrowserWidget;
class CMaterialImageListCtrl;
class QMaterialImageListModel;
class QTreeView;
class QAction;
struct IDataBaseItem;
class CMaterialBrowserRecord;
typedef std::vector<CMaterialBrowserRecord> TMaterialBrowserRecords;
namespace AzToolsFramework
{
namespace AssetBrowser
{
class AssetBrowserModel;
class AssetBrowserFilterModel;
class AssetTypeFilter;
}
}
enum ESccFileAttributes;
namespace Ui
{
class MaterialBrowser;
}
//////////////////////////////////////////////////////////////////////////
struct IMaterialBrowserListener
{
virtual void OnBrowserSelectItem(IDataBaseItem* pItem, bool bForce) = 0;
};
//////////////////////////////////////////////////////////////////////////
// MaterialBrowserWidget
//////////////////////////////////////////////////////////////////////////
class MaterialBrowserFilterModel;
class MaterialBrowserWidget
: public QWidget
, public IDataBaseManagerListener
, public IEditorNotifyListener
, public MaterialBrowserWidgetBus::Handler
{
Q_OBJECT
public:
enum EViewType
{
VIEW_LEVEL = 0,
VIEW_ALL = 1,
};
enum EFilter
{
eFilter_Materials = 0x01,
eFilter_Textures = 0x02,
eFilter_Materials_And_Textures = 0x03,
eFilter_Submaterials = 0x04
};
MaterialBrowserWidget(QWidget* parent);
~MaterialBrowserWidget();
void SetListener(IMaterialBrowserListener* pListener) { m_pListener = pListener; }
EViewType GetViewType() const { return m_viewType; };
void ClearItems();
void SelectItem(IDataBaseItem* pItem, IDataBaseItem* pParentItem);
void DeleteItem();
void PopulateItems();
void StartRecordUpdateJobs();
bool ShowCheckedOutRecursive(TMaterialBrowserRecords* pRecords);
void ShowOnlyLevelMaterials(bool levelOnly);
void OnCopy();
void OnCopyName();
void OnPaste();
void OnCut();
void OnDuplicate();
void OnAddNewMaterial();
void OnAddNewMultiMaterial();
void OnConvertToMulti();
void OnMergeMaterials();
public slots:
void OnSelectionChanged();
void OnSubMaterialSelectedInPreviewPane(const QModelIndex& current);
void SaveCurrentMaterial();
void OnRefreshSelection();
void OnMaterialAdded();
signals:
void refreshSelection();
void materialAdded();
public:
void OnUpdateShowCheckedOut();
bool CanPaste() const;
void SetImageListCtrl(CMaterialImageListCtrl* pCtrl);
//////////////////////////////////////////////////////////////////////////
// IDataBaseManagerListener implementation.
//////////////////////////////////////////////////////////////////////////
virtual void OnDataBaseItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event);
//////////////////////////////////////////////////////////////////////////
virtual void OnEditorNotifyEvent(EEditorNotifyEvent event);
void AddContextMenuActionsSingleSelection(QMenu &menu, _smart_ptr<CMaterial> material) const;
void OnContextMenuAction(int command, _smart_ptr<CMaterial> material);
// MaterialBrowserWidgetBus event handlers
void MaterialAddFinished() override;
void MaterialFinishedProcessing(_smart_ptr<CMaterial> material, const QPersistentModelIndex &filterModelIndex) override;
void MaterialRecordUpdateFinished() override;
protected:
// Item definition.
enum ESourceControlOp
{
ESCM_IMPORT,
ESCM_CHECKOUT,
ESCM_UNDO_CHECKOUT,
ESCM_GETLATEST,
ESCM_GETLATESTTEXTURES,
};
void DeleteItem(const CMaterialBrowserRecord &record);
void SetSelectedItem(_smart_ptr<CMaterial> material, const TMaterialBrowserRecords* pMarkedRecords, bool selectInTreeView);
void OnAddSubMtl();
void OnSelectAssignedObjects();
void OnAssignMaterialToSelection();
void OnRenameItem();
void OnResetItem();
void OnSetSubMtlCount(const CMaterialBrowserRecord &record);
void DoSourceControlOp(CMaterialBrowserRecord &record, ESourceControlOp);
void OnMakeSubMtlSlot(const CMaterialBrowserRecord &record);
void OnClearSubMtlSlot(_smart_ptr<CMaterial> subMaterial);
void SetSubMaterial(_smart_ptr<CMaterial> parentMaterial, int slot, _smart_ptr<CMaterial> subMaterial);
void OnSaveToFile(bool bMulti);
void RefreshSelected();
void TickRefreshMaterials();
void TryLoadRecordMaterial(CMaterialBrowserRecord &record);
void ShowContextMenu(const CMaterialBrowserRecord &record, const QPoint& point);
_smart_ptr<CMaterial> GetCurrentMaterial();
uint32 MaterialNameToCrc32(const QString& str);
bool TryGetSelectedRecord(CMaterialBrowserRecord &record);
AZStd::string GetSelectedMaterialID();
private:
void expandAllNotMatchingIndexes(const QModelIndex& parent = QModelIndex());
void ClearImageListControlSelection();
void ClearSelection(QMaterialImageListModel* materialModel);
QMenu *InitializeSearchMenu();
void AddContextMenuActionsMultiSelect(QMenu &menu) const;
void AddContextMenuActionsNoSelection(QMenu &menu) const;
void AddContextMenuActionsSubMaterial(QMenu &menu, _smart_ptr<CMaterial> parentMaterial, _smart_ptr<CMaterial> subMaterial) const;
void AddContextMenuActionsMultiMaterial(QMenu &menu) const;
void AddContextMenuActionsSingleMaterial(QMenu &menu) const;
void AddContextMenuActionsCommon(QMenu &menu, _smart_ptr<CMaterial> material) const;
void AddContextMenuActionsSourceControl(QMenu &menu, _smart_ptr<CMaterial> material, uint32 fileAttributes) const;
QScopedPointer<Ui::MaterialBrowser> m_ui;
AzToolsFramework::AssetBrowser::AssetBrowserModel* m_assetBrowserModel;
QSharedPointer<MaterialBrowserFilterModel> m_filterModel;
int m_selectedSubMaterialIndex = -1;
bool m_bIgnoreSelectionChange;
bool m_bItemsValid;
CMaterialManager* m_pMatMan;
IMaterialBrowserListener* m_pListener;
CMaterialImageListCtrl* m_pMaterialImageListCtrl;
EViewType m_viewType;
bool m_bNeedReload;
bool m_bHighlightMaterial;
uint32 m_timeOfHighlight;
TMaterialBrowserRecords m_markedRecords;
_smart_ptr<CMaterial> m_pLastActiveMultiMaterial;
_smart_ptr<CMaterial> m_delayedSelection;
bool m_bShowOnlyCheckedOut;
QAction* m_cutAction;
QAction* m_copyAction;
QAction* m_pasteAction;
QAction* m_duplicateAction;
QAction* m_deleteAction;
QAction* m_renameItemAction;
QAction* m_addNewMaterialAction;
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALBROWSER_H
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MaterialBrowser</class>
<widget class="QWidget" name="MaterialBrowser">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>250</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="AzToolsFramework::AssetBrowser::SearchWidget" name="m_searchWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>147</width>
<height>22</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="AzToolsFramework::AssetBrowser::AssetBrowserTreeView" name="treeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>AzToolsFramework::AssetBrowser::SearchWidget</class>
<extends>QWidget</extends>
<header>AzToolsFramework/AssetBrowser/Search/SearchWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>AzToolsFramework::AssetBrowser::AssetBrowserTreeView</class>
<extends>QTreeView</extends>
<header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="MaterialDialog.qrc"/>
</resources>
<connections/>
</ui>
@@ -1,652 +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 "EditorDefs.h"
#include "MaterialBrowserFilterModel.h"
// AzFramework
#include <AzCore/Jobs/JobFunction.h>
// AzToolsFramework
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
// Editor
#include "MaterialBrowserSearchFilters.h"
#include "MaterialManager.h"
namespace
{
// how often to re-query source control status of an item after querying it, in seconds.
// note that using a source control operation on an item invalidates the cache and will immediately
// refresh its status regardless of this value, so it can be pretty high.
qint64 g_timeRefreshSCCStatus = 60;
}
#define IDC_MATERIAL_TREECTRL 3
//////////////////////////////////////////////////////////////////////////
#define ITEM_IMAGE_SHARED_MATERIAL 0
#define ITEM_IMAGE_SHARED_MATERIAL_SELECTED 1
#define ITEM_IMAGE_FOLDER 2
#define ITEM_IMAGE_FOLDER_OPEN 3
#define ITEM_IMAGE_MATERIAL 4
#define ITEM_IMAGE_MATERIAL_SELECTED 5
#define ITEM_IMAGE_MULTI_MATERIAL 6
#define ITEM_IMAGE_MULTI_MATERIAL_SELECTED 7
#define ITEM_IMAGE_OVERLAY_CGF 8
#define ITEM_IMAGE_OVERLAY_INPAK 9
#define ITEM_IMAGE_OVERLAY_READONLY 10
#define ITEM_IMAGE_OVERLAY_ONDISK 11
#define ITEM_IMAGE_OVERLAY_LOCKED 12
#define ITEM_IMAGE_OVERLAY_CHECKEDOUT 13
#define ITEM_IMAGE_OVERLAY_NO_CHECKOUT 14
//////////////////////////////////////////////////////////////////////////
AZ::Data::AssetId GetMaterialProductAssetIdFromAssetBrowserEntry(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* assetEntry)
{
using namespace AzToolsFramework::AssetBrowser;
if (assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source ||
assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product)
{
AZStd::vector<const ProductAssetBrowserEntry*> products;
assetEntry->GetChildrenRecursively<ProductAssetBrowserEntry>(products);
// Cache the material asset type because this function is called for every submaterial when searching.
// AssetType is a POD struct so it should be fine to leave it as a static that gets destroyed during library unload/program termination.
static AZ::Data::AssetType materialAssetType = AZ::Data::AssetType::CreateNull();
if (materialAssetType.IsNull())
{
EBusFindAssetTypeByName materialAssetTypeResult("Material");
AZ::AssetTypeInfoBus::BroadcastResult(materialAssetTypeResult, &AZ::AssetTypeInfo::GetAssetType);
AZ_Assert(materialAssetTypeResult.Found(), "Could not find asset type for material asset");
materialAssetType = materialAssetTypeResult.GetAssetType();
}
for (const auto* product : products)
{
if (product->GetAssetType() == materialAssetType)
{
return product->GetAssetId();
}
}
}
return AZ::Data::AssetId();
}
MaterialBrowserFilterModel::MaterialBrowserFilterModel(QObject* parent)
: AzToolsFramework::AssetBrowser::AssetBrowserFilterModel(parent)
{
using namespace AzToolsFramework::AssetBrowser;
using namespace AzToolsFramework::MaterialBrowser;
MaterialBrowserSourceControlBus::Handler::BusConnect();
AssetBrowserModelNotificationBus::Handler::BusConnect();
MaterialBrowserRequestBus::Handler::BusConnect();
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_00.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_01.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_02.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_03.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_04.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_05.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_06.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/material_07.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_00.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_01.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_02.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_03.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_04.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_05.png"));
m_imageList.push_back(QPixmap(":/MaterialBrowser/images/filestatus_06.png"));
// Create an asset type filter for materials
AssetTypeFilter* assetTypeFilter = new AssetTypeFilter();
assetTypeFilter->SetAssetType("Material");
assetTypeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down); //this will make sure folders that contain materials are displayed
m_assetTypeFilter = FilterConstType(assetTypeFilter);
// Create search filters. SetSearchFilter stores these filters so that they are deleted when this object is deleted.
m_subMaterialSearchFilter = new SubMaterialSearchFilter(this);
m_levelMaterialSearchFilter = new LevelMaterialSearchFilter(this);
InitializeRecordUpdateJob();
}
MaterialBrowserFilterModel::~MaterialBrowserFilterModel()
{
SAFE_DELETE(m_jobCancelGroup);
SAFE_DELETE(m_jobContext);
SAFE_DELETE(m_jobManager);
AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler::BusDisconnect();
MaterialBrowserSourceControlBus::Handler::BusDisconnect();
AzToolsFramework::MaterialBrowser::MaterialBrowserRequestBus::Handler::BusDisconnect();
AzFramework::AssetCatalogEventBus::Handler::BusDisconnect();
}
void MaterialBrowserFilterModel::UpdateRecord(const QModelIndex& filterModelIndex)
{
using namespace AzToolsFramework::AssetBrowser;
if (filterModelIndex.isValid())
{
QModelIndex modelIndex = mapToSource(filterModelIndex);
AssetBrowserEntry* assetEntry = static_cast<AssetBrowserEntry*>(modelIndex.internalPointer());
if (assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source ||
assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product)
{
AZStd::vector<const ProductAssetBrowserEntry*> products;
assetEntry->GetChildrenRecursively<ProductAssetBrowserEntry>(products);
for (const auto* product : products)
{
if (!m_assetTypeFilter->Match(product))
{
continue;
}
MaterialBrowserRecordAssetBrowserData assetBrowserData;
assetBrowserData.assetId = product->GetAssetId();
assetBrowserData.relativeFilePath = product->GetRelativePath();
assetBrowserData.fullSourcePath = product->GetFullPath();
assetBrowserData.modelIndex = modelIndex;
assetBrowserData.filterModelIndex = filterModelIndex;
UpdateRecord(assetBrowserData);
}
}
}
}
void MaterialBrowserFilterModel::UpdateRecord(const MaterialBrowserRecordAssetBrowserData& assetBrowserData)
{
CMaterialBrowserRecord record;
record.SetAssetBrowserData(assetBrowserData);
record.m_material = GetIEditor()->GetMaterialManager()->LoadMaterial(record.GetRelativeFilePath().c_str());
SetRecord(record);
}
void MaterialBrowserFilterModel::UpdateSourceControlFileInfoCallback(const AZ::Data::AssetId& assetId, const AzToolsFramework::SourceControlFileInfo& info)
{
CMaterialBrowserRecord record;
bool found = m_materialRecordMap.find(assetId, &record);
if (found)
{
// Update the cached source control attributes for the record
record.m_lastCachedSCCAttributes = info;
record.m_lastCachedFileAttributes = static_cast<ESccFileAttributes>(CFileUtil::GetAttributes(record.GetFullSourcePath().c_str(), false));
record.m_lastCheckedSCCAttributes = QDateTime::currentDateTime();
// Update the record
m_materialRecordMap.erase(assetId);
m_materialRecordMap.insert(AZStd::pair<AZ::Data::AssetId, CMaterialBrowserRecord>(record.GetAssetId(), record));
QueueDataChangedEvent(record.GetFilterModelIndex());
}
}
void MaterialBrowserFilterModel::UpdateSourceControlLastCheckedTime(const AZ::Data::AssetId& assetId, const QDateTime& dateTime)
{
CMaterialBrowserRecord record;
bool found = m_materialRecordMap.find(assetId, &record);
if (found)
{
// Update the record
record.m_lastCheckedSCCAttributes = dateTime;
m_materialRecordMap.erase(assetId);
m_materialRecordMap.insert(AZStd::pair<AZ::Data::AssetId, CMaterialBrowserRecord>(record.GetAssetId(), record));
}
}
QVariant MaterialBrowserFilterModel::data(const QModelIndex& index, int role /* = Qt::DisplayRole*/) const
{
// Should return data from an AssetBrowserEntry, or get material specific info from that data
if (index.isValid())
{
// Use the base AssetBrowserFilterModel::data function for display role
if (role != AzToolsFramework::AssetBrowser::AssetBrowserModel::Roles::EntryRole)
{
QModelIndex modelIndex = mapToSource(index);
AzToolsFramework::AssetBrowser::AssetBrowserEntry* assetEntry = static_cast<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>(modelIndex.internalPointer());
AZ::Data::AssetId assetId = GetMaterialProductAssetIdFromAssetBrowserEntry(assetEntry);
if (assetId.IsValid())
{
CMaterialBrowserRecord record;
bool found = m_materialRecordMap.find(assetId, &record);
if (role == Qt::UserRole)
{
if (found)
{
return QVariant::fromValue(record);
}
else
{
return QVariant();
}
}
}
}
}
// If the role is Qt::DisplayRole, the item a folder, or the material has not been parsed yet, fall back on the default data result from the underlying AssetBrowserModel
return AzToolsFramework::AssetBrowser::AssetBrowserFilterModel::data(index, role);
}
void MaterialBrowserFilterModel::GetRelativeFilePaths(AZStd::vector<MaterialBrowserRecordAssetBrowserData>& files) const
{
GetRelativeFilePathsRecursive(files, this);
}
void MaterialBrowserFilterModel::GetRelativeFilePathsRecursive(AZStd::vector<MaterialBrowserRecordAssetBrowserData>& files,
const MaterialBrowserFilterModel* model, const QModelIndex& parent) const
{
using namespace AzToolsFramework::AssetBrowser;
for (int r = 0; r < model->rowCount(parent); ++r)
{
QModelIndex index = model->index(r, 0, parent);
QModelIndex modelIndex = model->mapToSource(index);
if (model->hasChildren(index))
{
GetRelativeFilePathsRecursive(files, model, index);
}
else
{
AssetBrowserEntry* assetEntry = static_cast<AssetBrowserEntry*>(modelIndex.internalPointer());
AZStd::vector<const ProductAssetBrowserEntry*> products;
assetEntry->GetChildrenRecursively<ProductAssetBrowserEntry>(products);
for (const auto* product : products)
{
if (!m_assetTypeFilter->Match(product))
{
continue;
}
MaterialBrowserRecordAssetBrowserData item;
item.assetId = product->GetAssetId();
item.fullSourcePath = product->GetFullPath();
item.relativeFilePath = product->GetRelativePath();
item.modelIndex = modelIndex;
item.filterModelIndex = index;
files.push_back(item);
}
}
}
}
QModelIndex MaterialBrowserFilterModel::GetIndexFromMaterial(_smart_ptr<CMaterial> material) const
{
CMaterialBrowserRecord record;
bool found = TryGetRecordFromMaterial(material, record);
if (found)
{
return record.GetFilterModelIndex();
}
return QModelIndex();
}
QModelIndex MaterialBrowserFilterModel::GetFilterModelIndex(const AZ::Data::AssetId& assetId) const
{
QModelIndex filterModelIndex;
if (TryGetFilterModelIndexRecursive(filterModelIndex, assetId, this))
{
return filterModelIndex;
}
return QModelIndex();
}
bool MaterialBrowserFilterModel::TryGetFilterModelIndexRecursive(QModelIndex& filterModelIndex,
const AZ::Data::AssetId& assetId, const MaterialBrowserFilterModel* model, const QModelIndex& parent) const
{
using namespace AzToolsFramework::AssetBrowser;
// Walk through the filter model to find the product entry with the corresponding assetId
for (int r = 0; r < model->rowCount(parent); ++r)
{
QModelIndex index = model->index(r, 0, parent);
QModelIndex modelIndex = model->mapToSource(index);
if (model->hasChildren(index))
{
if (TryGetFilterModelIndexRecursive(filterModelIndex, assetId, model, index))
{
return true;
}
}
else
{
// Check to see if the current entry is the one we're looking for
AssetBrowserEntry* assetEntry = static_cast<AssetBrowserEntry*>(modelIndex.internalPointer());
AZStd::vector<const ProductAssetBrowserEntry*> products;
assetEntry->GetChildrenRecursively<ProductAssetBrowserEntry>(products);
for (const auto* product : products)
{
if (assetId == product->GetAssetId())
{
filterModelIndex = index;
return true;
}
}
}
}
return false;
}
void MaterialBrowserFilterModel::EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry)
{
// If the entry is a product material
if (entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product && m_assetTypeFilter->Match(entry))
{
// capture the data here, so that entry cannot disappear before we actually get to the job.
MaterialBrowserRecordAssetBrowserData assetBrowserData;
assetBrowserData.assetId = GetMaterialProductAssetIdFromAssetBrowserEntry(entry);
assetBrowserData.relativeFilePath = entry->GetRelativePath();
assetBrowserData.fullSourcePath = entry->GetFullPath();
assetBrowserData.filterModelIndex = GetFilterModelIndex(assetBrowserData.assetId);
// Create a job to add/update the entry in the underlying map
AZ::Job* updateEntryJob = AZ::CreateJobFunction([this, assetBrowserData]()
{
CMaterialBrowserRecord record;
record.SetAssetBrowserData(assetBrowserData);
record.m_material = GetIEditor()->GetMaterialManager()->LoadMaterialWithFullSourcePath(record.GetRelativeFilePath().c_str(), record.GetFullSourcePath().c_str());
SetRecord(record);
MaterialBrowserWidgetBus::Broadcast(&MaterialBrowserWidgetEvents::MaterialAddFinished);
}, true, m_jobContext);
// Start the job immediately
AZ::Job* currentJob = m_jobContext->GetJobManager().GetCurrentJob();
if (currentJob)
{
// Suspend the current job until the new job completes so that
// if a new material is created by the user it's ready to use sooner
currentJob->StartAsChild(updateEntryJob);
currentJob->WaitForChildren();
}
else
{
updateEntryJob->Start();
}
}
}
void MaterialBrowserFilterModel::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId)
{
CMaterialBrowserRecord record;
bool found = m_materialRecordMap.find(assetId, &record);
if (found)
{
record.m_material->Reload();
//Send out event to notify UI update if it's currently selected
MaterialBrowserWidgetBus::Broadcast(&MaterialBrowserWidgetEvents::MaterialFinishedProcessing, record.m_material, record.GetFilterModelIndex());
}
}
bool MaterialBrowserFilterModel::HasRecord(const AZ::Data::AssetId& assetId)
{
return m_materialRecordMap.find(assetId);
}
bool MaterialBrowserFilterModel::IsMultiMaterial(const AZ::Data::AssetId& assetId)
{
CMaterialBrowserRecord record;
bool found = m_materialRecordMap.find(assetId, &record);
if (found)
{
if (record.m_material && record.m_material->IsMultiSubMaterial())
{
return true;
}
}
return false;
}
bool MaterialBrowserFilterModel::TryGetRecordFromMaterial(_smart_ptr<CMaterial> material, CMaterialBrowserRecord& record) const
{
if (material)
{
// Get the relative path for the material
bool pathFound = false;
AZStd::string relativePath;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(pathFound, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath, material->GetFilename().toUtf8().data(), relativePath);
AZ_Assert(pathFound, "Failed to get engine relative path from %s", material->GetFilename().toUtf8().data());
// Get the assetId from the relative path
AZ::Data::AssetId assetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath, relativePath.c_str(), GetIEditor()->GetMaterialManager()->GetMaterialAssetType(), false);
return TryGetRecordFromAssetId(assetId, record);
}
return false;
}
bool MaterialBrowserFilterModel::TryGetRecordFromAssetId(const AZ::Data::AssetId& assetId, CMaterialBrowserRecord& record) const
{
bool recordFound = m_materialRecordMap.find(assetId, &record);
return recordFound;
}
void MaterialBrowserFilterModel::SetRecord(const CMaterialBrowserRecord& record)
{
m_materialRecordMap.erase(record.GetAssetId());
m_materialRecordMap.insert({ record.GetAssetId(), record });
QueueDataChangedEvent(record.GetFilterModelIndex());
}
void MaterialBrowserFilterModel::SetSearchFilter(const AzToolsFramework::AssetBrowser::SearchWidget* searchWidget)
{
/*
* The filter matches the following rule:
* A. If the entry is a material
* 1. The material's name matches the search text
* 2. The sub material's name matches the search text
* B. If the entry is a folder:
* 1. The folder's name matches the search text
* 2. The folder contains a material matching A
* 3. The folder contains a folder matching B.1 & B.2
*/
using namespace AzToolsFramework::AssetBrowser;
m_searchWidget = searchWidget;
// Create a search filter where a search text either matches entry/entry parent's name or sub material name
CompositeFilter* nameFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::OR);
QSharedPointer<CompositeFilter> searchWidgetFilter = m_searchWidget->GetFilter();
// The default setting for search widget filter is Down
// Since now we only need to match for the entry itself in this filter, set back to None
searchWidgetFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::None);
nameFilter->AddFilter(FilterConstType(m_subMaterialSearchFilter));
nameFilter->AddFilter(FilterConstType(searchWidgetFilter));
EntryTypeFilter* productsFilter = new EntryTypeFilter();
productsFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Product);
InverseFilter* noProductsFilter = new InverseFilter();
noProductsFilter->SetFilter(FilterConstType(productsFilter));
// Create a filter where the entry needs to match the previous name filter and it needs to be material itself or it contains material.
CompositeFilter* isMaterialAndMatchesSearchFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
isMaterialAndMatchesSearchFilter->AddFilter(FilterConstType(nameFilter));
isMaterialAndMatchesSearchFilter->AddFilter(FilterConstType(m_assetTypeFilter));
isMaterialAndMatchesSearchFilter->AddFilter(FilterConstType(noProductsFilter));
isMaterialAndMatchesSearchFilter->AddFilter(FilterConstType(m_levelMaterialSearchFilter));
// Make sure any folder contains the matching result is included
isMaterialAndMatchesSearchFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
// Set the filter for the MaterialBrowserFilterModel
SetFilter(FilterConstType(isMaterialAndMatchesSearchFilter));
}
void MaterialBrowserFilterModel::ShowOnlyLevelMaterials(bool levelOnly, bool invalidateFilterNow)
{
m_levelMaterialSearchFilter->ShowOnlyLevelMaterials(levelOnly);
if (levelOnly)
{
m_levelMaterialSearchFilter->CacheLoadedMaterials();
}
if (invalidateFilterNow)
{
// we need to invalid the filter immediately, for example this is used when we are changing level, otherwise
// the current filter is used when getting file paths for all of the materials as part of StartRecordUpdateJobs.
invalidateFilter();
}
else
{
filterUpdatedSlot();
}
}
void MaterialBrowserFilterModel::SearchFilterUpdated()
{
m_subMaterialSearchFilter->SetFilterString(m_searchWidget->textFilter());
filterUpdatedSlot();
}
void MaterialBrowserFilterModel::QueueDataChangedEvent(const QPersistentModelIndex& filterModelIndex)
{
// Queue a data changed event to be executed on the main thread
AZStd::function<void()> emitDataChanged =
[this, filterModelIndex]()
{
if (filterModelIndex.isValid())
{
Q_EMIT dataChanged(filterModelIndex, filterModelIndex);
}
};
AZ::TickBus::QueueFunction(emitDataChanged);
}
void MaterialBrowserFilterModel::InitializeRecordUpdateJob()
{
AZ::JobManagerDesc desc;
AZ::JobManagerThreadDesc threadDesc;
for (size_t i = 0; i < AZStd::thread::hardware_concurrency(); ++i)
{
desc.m_workerThreads.push_back(threadDesc);
}
// Check to ensure these have not already been initialized.
AZ_Error("Material Browser", !m_jobManager && !m_jobCancelGroup && !m_jobContext, "MaterialBrowserFilterModel::InitializeRecordUpdateJob is being called again after it has already been initialized");
m_jobManager = aznew AZ::JobManager(desc);
m_jobCancelGroup = aznew AZ::JobCancelGroup();
m_jobContext = aznew AZ::JobContext(*m_jobManager, *m_jobCancelGroup);
}
void MaterialBrowserFilterModel::StartRecordUpdateJobs()
{
// Generate a list of file paths, assetId's, and asset browser model indices
// This must be done on the main thread, otherwise it can lead to a crash when the tree view UI is being initialized
AZStd::vector<MaterialBrowserRecordAssetBrowserData> files;
GetRelativeFilePaths(files);
// Kick off the background process that will iterate over the list of file paths and update the material record map
m_mainUpdateRecordJob = aznew MaterialBrowserUpdateJobCreator(this, files, m_jobContext);
m_mainUpdateRecordJob->Start();
}
void MaterialBrowserFilterModel::CancelRecordUpdateJobs()
{
m_jobContext->GetCancelGroup()->Cancel();
m_jobContext->GetCancelGroup()->Reset();
}
void MaterialBrowserFilterModel::ClearRecordMap()
{
CancelRecordUpdateJobs();
m_materialRecordMap.clear();
}
MaterialBrowserUpdateJobCreator::MaterialBrowserUpdateJobCreator(MaterialBrowserFilterModel* model, AZStd::vector<MaterialBrowserRecordAssetBrowserData>& files, AZ::JobContext* context /*= NULL*/)
: Job(true, context)
, m_files(files)
, m_filterModel(model)
{
}
void MaterialBrowserUpdateJobCreator::Process()
{
// Split the files to be processed evenly among threads
int numJobs = GetContext()->GetJobManager().GetNumWorkerThreads();
int materialsPerJob = (m_files.size() / numJobs) + 1;
for (auto it = m_files.begin(); it <= m_files.end(); it += materialsPerJob)
{
// Create a subset of the list of material files to be processed by another job
auto start = it;
auto end = it + materialsPerJob;
if (end > m_files.end())
{
end = m_files.end();
}
AZStd::vector<MaterialBrowserRecordAssetBrowserData> subset(start, end);
if (subset.size() > 0)
{
AZ::Job* materialBrowserUpdateJob = aznew MaterialBrowserUpdateJob(m_filterModel, subset, GetContext());
StartAsChild(materialBrowserUpdateJob);
}
}
WaitForChildren();
MaterialBrowserWidgetBus::Broadcast(&MaterialBrowserWidgetEvents::MaterialRecordUpdateFinished);
}
MaterialBrowserUpdateJob::MaterialBrowserUpdateJob(MaterialBrowserFilterModel* model, AZStd::vector<MaterialBrowserRecordAssetBrowserData>& files, AZ::JobContext* context /*= NULL*/)
: Job(true, context)
, m_filterModel(model)
, m_files(files)
{
}
void MaterialBrowserUpdateJob::Process()
{
for (size_t i = 0; i < m_files.size(); ++i)
{
// Early out when the job is cancelled
if (IsCancelled())
{
return;
}
CMaterialBrowserRecord record;
record.SetAssetBrowserData(m_files[i]);
// Get the writable status of the file, but don't update source control status until it is actually needed
record.m_lastCachedFileAttributes = static_cast<ESccFileAttributes>(CFileUtil::GetAttributes(record.GetFullSourcePath().c_str(), false));
record.m_material = GetIEditor()->GetMaterialManager()->LoadMaterialWithFullSourcePath(record.GetRelativeFilePath().c_str(), record.GetFullSourcePath().c_str());
m_filterModel->SetRecord(record);
}
}
@@ -1,240 +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/std/parallel/containers/concurrent_unordered_map.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/Jobs/Job.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <AzToolsFramework/AssetBrowser/Search/SearchWidget.h>
#include <AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <ISourceControl.h>
#include <QDateTime>
namespace AZ
{
class Job;
class JobManager;
class JobCancelGroup;
class JobContext;
}
class SubMaterialSearchFilter;
class LevelMaterialSearchFilter;
//////////////////////////////////////////////////////////////////////////
// Item class for browser.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
struct MaterialBrowserRecordAssetBrowserData
{
AZ::Data::AssetId assetId;
AZStd::string relativeFilePath;
AZStd::string fullSourcePath;
QPersistentModelIndex modelIndex;
QPersistentModelIndex filterModelIndex;
};
class CMaterialBrowserRecord
{
public:
CMaterialBrowserRecord()
{
InitializeSourceControlAttributes();
}
CMaterialBrowserRecord(const CMaterialBrowserRecord &rhs)
: m_material(rhs.m_material)
, m_lastCachedSCCAttributes(rhs.m_lastCachedSCCAttributes)
, m_lastCachedFileAttributes(rhs.m_lastCachedFileAttributes)
, m_lastCheckedSCCAttributes(rhs.m_lastCheckedSCCAttributes)
, m_assetBrowserData(rhs.m_assetBrowserData)
{
}
AZ::Data::AssetId GetAssetId() const { return m_assetBrowserData.assetId; }
AZStd::string GetRelativeFilePath() const { return m_assetBrowserData.relativeFilePath; }
AZStd::string GetFullSourcePath() const { return m_assetBrowserData.fullSourcePath; }
QPersistentModelIndex GetModelIndex() const { return m_assetBrowserData.modelIndex; }
QPersistentModelIndex GetFilterModelIndex() const { return m_assetBrowserData.filterModelIndex; }
void SetAssetBrowserData(const MaterialBrowserRecordAssetBrowserData &assetBrowserData) { m_assetBrowserData = assetBrowserData; }
void InitializeSourceControlAttributes()
{
// Force an update by setting the last update time to 1 / 1 / 1
m_lastCachedSCCAttributes = AzToolsFramework::SourceControlFileInfo();
m_lastCachedFileAttributes = SCC_FILE_ATTRIBUTE_INVALID;
m_lastCheckedSCCAttributes = QDate(1, 1, 1).startOfDay();
}
public:
_smart_ptr<CMaterial> m_material = nullptr;
AzToolsFramework::SourceControlFileInfo m_lastCachedSCCAttributes;
ESccFileAttributes m_lastCachedFileAttributes;
QDateTime m_lastCheckedSCCAttributes;
private:
MaterialBrowserRecordAssetBrowserData m_assetBrowserData;
};
Q_DECLARE_METATYPE(CMaterialBrowserRecord)
//! MaterialBrowserSourceControlEvents
//! This bus informs the material browser filter model
//! when an ASYNC source control command has completed
class MaterialBrowserSourceControlEvents
: public AZ::EBusTraits
{
public:
typedef AZStd::recursive_mutex MutexType;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; // there's only one listener
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; // theres only one listener
virtual ~MaterialBrowserSourceControlEvents() {}
//! Signals the callback for the GetFileInfo source control op
virtual void UpdateSourceControlFileInfoCallback(const AZ::Data::AssetId &assetId, const AzToolsFramework::SourceControlFileInfo& fileInfo) = 0;
//! Updates the timestamp for when the source control status was last checked
virtual void UpdateSourceControlLastCheckedTime(const AZ::Data::AssetId &assetId, const QDateTime &dateTime) = 0;
};
using MaterialBrowserSourceControlBus = AZ::EBus<MaterialBrowserSourceControlEvents>;
//! MaterialBrowserWidgetEvents
//! This bus is used to send events to the material browser widget
class MaterialBrowserWidgetEvents
: public AZ::EBusTraits
{
public:
typedef AZStd::recursive_mutex MutexType;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; // there's only one listener
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; // theres only one listener
virtual ~MaterialBrowserWidgetEvents() {}
//! Indicates that a material has finished being processed by the asset processor
virtual void MaterialFinishedProcessing(_smart_ptr<CMaterial> material, const QPersistentModelIndex &filterModelIndex) = 0;
//! Indicates that a material has finished being added to the material browser
virtual void MaterialAddFinished() = 0;
//! Indicates that the material record update for initially populating the material browser has finished
virtual void MaterialRecordUpdateFinished() = 0;
};
using MaterialBrowserWidgetBus = AZ::EBus<MaterialBrowserWidgetEvents>;
/**
* Get the product material assetId for a given AssetBrowserEntry
* If there is no valid product material, the material has not been processed, or there are multiple product materials
* and thus there is not an individual material that can be assumed based on the source, an invalid assetId is returned
* @param assetEntry An asset entry that may be a source or a product
* @return The assetId of the product material.
*/
AZ::Data::AssetId GetMaterialProductAssetIdFromAssetBrowserEntry(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* assetEntry);
class MaterialBrowserFilterModel
: public AzToolsFramework::AssetBrowser::AssetBrowserFilterModel
, public MaterialBrowserSourceControlBus::Handler
, public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler
, public AzToolsFramework::MaterialBrowser::MaterialBrowserRequestBus::Handler
, private AzFramework::AssetCatalogEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MaterialBrowserFilterModel, AZ::SystemAllocator, 0);
MaterialBrowserFilterModel(QObject* parent);
~MaterialBrowserFilterModel();
void UpdateRecord(const QModelIndex& filterModelIndex);
void UpdateRecord(const MaterialBrowserRecordAssetBrowserData &assetBrowserData);
void UpdateSourceControlFileInfoCallback(const AZ::Data::AssetId &assetId, const AzToolsFramework::SourceControlFileInfo& info) override;
void UpdateSourceControlLastCheckedTime(const AZ::Data::AssetId &assetId, const QDateTime &dateTime) override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
bool TryGetRecordFromMaterial(_smart_ptr<CMaterial> material, CMaterialBrowserRecord& record) const;
bool TryGetRecordFromAssetId(const AZ::Data::AssetId &assetId, CMaterialBrowserRecord& record) const;
void SetRecord(const CMaterialBrowserRecord& record);
void SetSearchFilter(const AzToolsFramework::AssetBrowser::SearchWidget* searchWidget);
void StartRecordUpdateJobs();
void CancelRecordUpdateJobs();
void ClearRecordMap();
void GetRelativeFilePaths(AZStd::vector<MaterialBrowserRecordAssetBrowserData> &files) const;
QModelIndex GetIndexFromMaterial(_smart_ptr<CMaterial> material) const;
QModelIndex GetFilterModelIndex(const AZ::Data::AssetId &assetId) const;
// AssetBrowserModelNotificationBus event handlers
void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override;
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
// MaterialBrowserRequestBus
bool HasRecord(const AZ::Data::AssetId& assetId) override;
bool IsMultiMaterial(const AZ::Data::AssetId& assetId) override;
void ShowOnlyLevelMaterials(bool levelOnly, bool invalidateFilterNow = false);
public Q_SLOTS:
void SearchFilterUpdated();
private:
void GetRelativeFilePathsRecursive(AZStd::vector<MaterialBrowserRecordAssetBrowserData> &files, const MaterialBrowserFilterModel* model, const QModelIndex &parent = QModelIndex()) const;
bool TryGetFilterModelIndexRecursive(QModelIndex &filterModelIndex, const AZ::Data::AssetId &assetId, const MaterialBrowserFilterModel* model, const QModelIndex &parent = QModelIndex()) const;
void QueueDataChangedEvent(const QPersistentModelIndex &filterModelIndex);
AZStd::concurrent_unordered_map<AZ::Data::AssetId, CMaterialBrowserRecord> m_materialRecordMap;
QVector<QPixmap> m_imageList;
AzToolsFramework::AssetBrowser::FilterConstType m_assetTypeFilter;
SubMaterialSearchFilter* m_subMaterialSearchFilter;
LevelMaterialSearchFilter* m_levelMaterialSearchFilter;
const AzToolsFramework::AssetBrowser::SearchWidget* m_searchWidget;
void InitializeRecordUpdateJob();
AZ::JobManager* m_jobManager = nullptr;
AZ::JobCancelGroup* m_jobCancelGroup = nullptr;
AZ::JobContext* m_jobContext = nullptr;
AZ::Job* m_mainUpdateRecordJob = nullptr;
};
/**
* Job that walks through a MaterialBrowserFilterModel to generate a list of files,
* then divides the list amongst child jobs for processing
*/
class MaterialBrowserUpdateJobCreator
: public AZ::Job
{
public:
AZ_CLASS_ALLOCATOR(MaterialBrowserUpdateJobCreator, AZ::ThreadPoolAllocator, 0);
MaterialBrowserUpdateJobCreator(MaterialBrowserFilterModel* model, AZStd::vector<MaterialBrowserRecordAssetBrowserData>& files, AZ::JobContext* context = nullptr);
void Process() override;
private:
MaterialBrowserFilterModel* m_filterModel;
AZStd::vector<MaterialBrowserRecordAssetBrowserData> m_files;
};
/**
* Job that walks through a list of material files, loads them, and then populates
* the MaterialBrowserFilterModel's map of material data
*/
class MaterialBrowserUpdateJob
: public AZ::Job
{
public:
AZ_CLASS_ALLOCATOR(MaterialBrowserUpdateJob, AZ::ThreadPoolAllocator, 0);
MaterialBrowserUpdateJob(MaterialBrowserFilterModel* model, AZStd::vector<MaterialBrowserRecordAssetBrowserData> &files, AZ::JobContext* context = nullptr);
void Process() override;
private:
MaterialBrowserFilterModel* m_filterModel;
AZStd::vector<MaterialBrowserRecordAssetBrowserData> m_files;
};
@@ -1,140 +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 "EditorDefs.h"
#include "MaterialBrowserSearchFilters.h"
// Editor
#include "MaterialBrowserFilterModel.h"
#include "Material.h"
SubMaterialSearchFilter::SubMaterialSearchFilter(const MaterialBrowserFilterModel* filterModel)
: m_filterModel(filterModel)
{
AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
}
void SubMaterialSearchFilter::SetFilterString(const QString& filterString)
{
m_filterString = filterString;
}
QString SubMaterialSearchFilter::GetNameInternal() const
{
return "SubMaterialSearchFilter";
}
bool SubMaterialSearchFilter::MatchInternal(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
{
// All entries match if there is no search string
if (m_filterString.isEmpty())
{
return true;
}
if (m_filterModel)
{
// Get the product material for the given asset browser entry
AZ::Data::AssetId assetId = GetMaterialProductAssetIdFromAssetBrowserEntry(entry);
if (assetId.IsValid())
{
CMaterialBrowserRecord record;
bool found = m_filterModel->TryGetRecordFromAssetId(assetId, record);
if (found)
{
// If there is a valid product material, check to see if any of its sub-materials match the search string
if (record.m_material)
{
for (int i = 0; i < record.m_material->GetSubMaterialCount(); ++i)
{
CMaterial* subMaterial = record.m_material->GetSubMaterial(i);
if (subMaterial)
{
// If any of the product sub-materials matches the string, return true for this entry
if (subMaterial->GetName().contains(m_filterString, Qt::CaseInsensitive))
{
return true;
}
}
}
}
}
}
}
return false;
}
LevelMaterialSearchFilter::LevelMaterialSearchFilter(const MaterialBrowserFilterModel* filterModel)
: m_filterModel(filterModel)
{
AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
}
QString LevelMaterialSearchFilter::GetNameInternal() const
{
return "LoadedMaterialSearchFilter";
}
void LevelMaterialSearchFilter::CacheLoadedMaterials()
{
m_localMap.clear();
AZStd::vector<IRenderNode*> foundRenderNodes;
unsigned int numFoundObjects = 0;
numFoundObjects = GetIEditor()->Get3DEngine()->GetObjectsByFlags(0);
foundRenderNodes.resize(numFoundObjects, nullptr);
GetIEditor()->Get3DEngine()->GetObjectsByFlags(0, foundRenderNodes.data());
AZStd::vector<_smart_ptr<IMaterial>> materials;
materials.reserve(foundRenderNodes.size());
for (IRenderNode* renderNode : foundRenderNodes)
{
renderNode->GetMaterials(materials);
}
for (size_t i = 0; i < materials.size(); ++i)
{
if (materials[i])
{
m_localMap[materials[i]->GetName()] = materials[i];
}
}
}
bool LevelMaterialSearchFilter::MatchInternal(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const
{
// All entries match if show level materials isn't selected
if (!m_onlyShowLevelMaterials)
{
return true;
}
// Get the product material for the given asset browser entry
AZ::Data::AssetId assetId = GetMaterialProductAssetIdFromAssetBrowserEntry(entry);
if (assetId.IsValid() && m_filterModel)
{
CMaterialBrowserRecord record;
bool found = m_filterModel->TryGetRecordFromAssetId(assetId, record);
if (found && record.m_material)
{
// If there is a valid product material, check to see if it is used by the level
return m_localMap.find(record.m_material->GetName()) != m_localMap.end();
}
}
return false;
}
#include <Material/moc_MaterialBrowserSearchFilters.cpp>
@@ -1,64 +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/AssetBrowser/Search/Filter.h>
#include <QHash>
#endif
class MaterialBrowserFilterModel;
//! Filter that checks the name of each sub-material in a material to see if it contains the filter string
class SubMaterialSearchFilter
: public AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter
{
Q_OBJECT
public:
SubMaterialSearchFilter(const MaterialBrowserFilterModel* filterModel);
~SubMaterialSearchFilter() override = default;
void SetFilterString(const QString& filterString);
protected:
QString GetNameInternal() const override;
bool MatchInternal(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
private:
bool TextMatchesFilter(const QString &text) const;
QString m_filterString = "";
const MaterialBrowserFilterModel* m_filterModel = nullptr;
};
class LevelMaterialSearchFilter
: public AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter
{
Q_OBJECT
public:
LevelMaterialSearchFilter(const MaterialBrowserFilterModel* filterModel);
~LevelMaterialSearchFilter() override = default;
void ShowOnlyLevelMaterials(bool onlyLevel) { m_onlyShowLevelMaterials = onlyLevel; }
void CacheLoadedMaterials();
protected:
QString GetNameInternal() const override;
bool MatchInternal(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) const override;
private:
bool m_onlyShowLevelMaterials = false;
const MaterialBrowserFilterModel* m_filterModel = nullptr;
using MaterialMap = QHash<QString, _smart_ptr<IMaterial> >;
MaterialMap m_localMap;
};
@@ -1,23 +0,0 @@
<RCC>
<qresource prefix="/MaterialBrowser">
<file>images/material_browser_00.png</file>
<file>images/material_browser_01.png</file>
<file>images/material_browser_02.png</file>
<file>images/material_browser_03.png</file>
<file>images/material_00.png</file>
<file>images/material_01.png</file>
<file>images/material_02.png</file>
<file>images/material_03.png</file>
<file>images/material_04.png</file>
<file>images/material_05.png</file>
<file>images/material_06.png</file>
<file>images/material_07.png</file>
<file>images/filestatus_00.png</file>
<file>images/filestatus_01.png</file>
<file>images/filestatus_02.png</file>
<file>images/filestatus_03.png</file>
<file>images/filestatus_04.png</file>
<file>images/filestatus_05.png</file>
<file>images/filestatus_06.png</file>
</qresource>
</RCC>
@@ -1,372 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "MaterialHelpers.h"
namespace MaterialHelpers
{
//////////////////////////////////////////////////////////////////////////
static void ParsePublicParamsScript(const char* sUIScript, IVariable* pVar)
{
string uiscript = sUIScript;
string element[3];
int p1 = 0;
string itemToken = uiscript.Tokenize(";", p1);
while (!itemToken.empty())
{
int nElements = 0;
int p2 = 0;
string token = itemToken.Tokenize(" \t\r\n=", p2);
while (!token.empty())
{
element[nElements++] = token;
if (nElements == 2)
{
element[nElements] = itemToken.substr(p2);
element[nElements].Trim(" =\t\"");
break;
}
token = itemToken.Tokenize(" \t\r\n=", p2);
}
float minLimit, maxLimit;
pVar->GetLimits(minLimit, maxLimit);
if (azstricmp(element[1], "UIWidget") == 0)
{
if (azstricmp(element[2], "Color") == 0)
{
pVar->SetDataType(IVariable::DT_COLOR);
}
}
else if (azstricmp(element[1], "UIHelp") == 0)
{
string help = element[2];
help.replace("\\n", "\n");
pVar->SetDescription(help);
}
else if (azstricmp(element[1], "UIName") == 0)
{
pVar->SetHumanName(element[2].c_str());
}
else if (azstricmp(element[1], "UIMin") == 0)
{
pVar->SetLimits(atof(element[2]), maxLimit);
}
else if (azstricmp(element[1], "UIMax") == 0)
{
pVar->SetLimits(minLimit, atof(element[2]));
}
else if (azstricmp(element[1], "UIStep") == 0)
{
}
itemToken = uiscript.Tokenize(";", p1);
}
}
//////////////////////////////////////////////////////////////////////////
static void AddRealNameToDescription(IVariable* pIVar, const SShaderParam* pParam)
{
// In order to help the user discover the true names of parameters, info they need using certain script functions,
// we embed the real parameter name in the description.
QString description = pIVar->GetDescription();
if (!description.isEmpty())
{
description += "\n";
}
description += "(Script Param Name = ";
description += pParam->m_Name.c_str();
description += ")";
pIVar->SetDescription(description);
}
//////////////////////////////////////////////////////////////////////////
CVarBlock* GetPublicVars(SInputShaderResources& pShaderResources)
{
if (pShaderResources.m_ShaderParams.empty())
{
return 0;
}
CVarBlock* pPublicVars = new CVarBlock;
for (int i = 0; i < pShaderResources.m_ShaderParams.size(); i++)
{
IVariable* pIVar = NULL;
SShaderParam* pParam = &pShaderResources.m_ShaderParams[i];
switch (pParam->m_Type)
{
case eType_BYTE:
pIVar = new CVariable<int>(pParam->m_Value.m_Byte);
break;
case eType_SHORT:
pIVar = new CVariable<int>(pParam->m_Value.m_Short);
break;
case eType_INT:
pIVar = new CVariable<int>(pParam->m_Value.m_Int);
break;
case eType_FLOAT:
pIVar = new CVariable<float>(pParam->m_Value.m_Float);
break;
/* case eType_STRING:
pIVar = new CVariable<string>(pParam->m_Value.m_String);
break; */
case eType_FCOLOR:
pIVar = new CVariable<Vec3>(Vec3(pParam->m_Value.m_Color[0], pParam->m_Value.m_Color[1], pParam->m_Value.m_Color[2]));
pIVar->SetDataType(IVariable::DT_COLOR);
break;
case eType_FCOLORA:
pIVar = new CVariable<Vec4>(Vec4(pParam->m_Value.m_Color[0], pParam->m_Value.m_Color[1], pParam->m_Value.m_Color[2], pParam->m_Value.m_Color[3]));
pIVar->SetDataType(IVariable::DT_COLORA);
break;
case eType_VECTOR:
pIVar = new CVariable<Vec3>(Vec3(pParam->m_Value.m_Vector[0], pParam->m_Value.m_Vector[1], pParam->m_Value.m_Vector[2]));
break;
default:
break;
}
if (pIVar)
{
pIVar->SetName(pParam->m_Name.c_str());
pPublicVars->AddVariable(pIVar);
if (pParam->m_Script.size())
{
ParsePublicParamsScript(pParam->m_Script.c_str(), pIVar);
}
AddRealNameToDescription(pIVar, pParam);
}
}
return pPublicVars;
}
void SetPublicVars(CVarBlock* pPublicVars, SInputShaderResources& pInputShaderResources)
{
assert(pPublicVars);
if (pInputShaderResources.m_ShaderParams.empty())
{
return;
}
int numVars = pPublicVars->GetNumVariables();
for (int i = 0; i < numVars; i++)
{
if (i >= numVars)
{
break;
}
IVariable* pVar = pPublicVars->GetVariable(i);
SShaderParam* pParam = NULL;
for (int j = 0; j < pInputShaderResources.m_ShaderParams.size(); j++)
{
if (QString::compare(pVar->GetName(), pInputShaderResources.m_ShaderParams[j].m_Name.c_str()) == 0)
{
pParam = &pInputShaderResources.m_ShaderParams[j];
break;
}
}
if (!pParam)
{
continue;
}
switch (pParam->m_Type)
{
case eType_BYTE:
if (pVar->GetType() == IVariable::INT)
{
int val = 0;
pVar->Get(val);
pParam->m_Value.m_Byte = val;
}
break;
case eType_SHORT:
if (pVar->GetType() == IVariable::INT)
{
int val = 0;
pVar->Get(val);
pParam->m_Value.m_Short = val;
}
break;
case eType_INT:
if (pVar->GetType() == IVariable::INT)
{
int val = 0;
pVar->Get(val);
pParam->m_Value.m_Int = val;
}
break;
case eType_FLOAT:
if (pVar->GetType() == IVariable::FLOAT)
{
float val = 0;
pVar->Get(val);
pParam->m_Value.m_Float = val;
}
break;
/*
case eType_STRING:
if (pVar->GetType() == IVariable::STRING)
{
CString str;
int val = 0;
pVar->Get(val);
pParam->m_Value.m_Byte = val;
}
break;
*/
case eType_FCOLOR:
case eType_FCOLORA:
if (pVar->GetType() == IVariable::VECTOR4 && (pVar->GetDataType() == IVariable::DT_COLOR || pVar->GetDataType() == IVariable::DT_COLORA))
{
Vec4 val(0, 0, 0, 0);
pVar->Get(val);
pParam->m_Value.m_Color[0] = val.x;
pParam->m_Value.m_Color[1] = val.y;
pParam->m_Value.m_Color[2] = val.z;
pParam->m_Value.m_Color[3] = val.w;
}
else if (pVar->GetType() == IVariable::VECTOR && (pVar->GetDataType() == IVariable::DT_COLOR || pVar->GetDataType() == IVariable::DT_COLORA))
{
Vec3 val(0, 0, 0);
pVar->Get(val);
pParam->m_Value.m_Color[0] = val.x;
pParam->m_Value.m_Color[1] = val.y;
pParam->m_Value.m_Color[2] = val.z;
}
break;
case eType_VECTOR:
if (pVar->GetType() == IVariable::VECTOR)
{
Vec3 val(0, 0, 0);
pVar->Get(val);
pParam->m_Value.m_Vector[0] = val.x;
pParam->m_Value.m_Vector[1] = val.y;
pParam->m_Value.m_Vector[2] = val.z;
}
break;
default:
break;
}
}
}
void SetPublicVars(CVarBlock* pPublicVars, SInputShaderResources& pInputShaderResources, IRenderShaderResources* pRenderShaderResources, IShader* pShader)
{
SetPublicVars(pPublicVars, pInputShaderResources);
// Set shader params.
if (pRenderShaderResources)
{
pRenderShaderResources->SetShaderParams(&pInputShaderResources, pShader);
}
}
//////////////////////////////////////////////////////////////////////////
CVarBlock* GetShaderGenParamsVars(IShader* pShader, uint64 nShaderGenMask)
{
IShader* pTemplShader = pShader;
if (!pTemplShader)
{
return 0;
}
SShaderGen* pShaderGen = pTemplShader->GetGenerationParams();
if (!pShaderGen)
{
return 0;
}
CVarBlock* pBlock = new CVarBlock;
for (int i = 0; i < pShaderGen->m_BitMask.size(); i++)
{
SShaderGenBit* pGenBit = pShaderGen->m_BitMask[i];
if (pGenBit->m_Flags & SHGF_HIDDEN)
{
continue;
}
if (!pGenBit->m_ParamProp.empty())
{
CVariable<bool>* pVar = new CVariable<bool>;
pBlock->AddVariable(pVar);
pVar->SetName(pGenBit->m_ParamProp.c_str());
*pVar = (pGenBit->m_Mask & nShaderGenMask) != 0;
pVar->SetDescription(pGenBit->m_ParamDesc.c_str());
}
}
/*
// make sure if no valid generation parameters to not create new tab
if (!pBlock->GetVarsCount())
{
SAFE_DELETE(pBlock);
return 0;
}
*/
return pBlock;
}
//////////////////////////////////////////////////////////////////////////
uint64 SetShaderGenParamsVars(IShader* pShader, CVarBlock* pBlock)
{
IShader* pTemplShader = pShader;
if (!pTemplShader)
{
return 0;
}
SShaderGen* pShaderGen = pTemplShader->GetGenerationParams();
if (!pShaderGen)
{
return 0;
}
uint64 nGenMask = 0;
for (int i = 0; i < pShaderGen->m_BitMask.size(); i++)
{
SShaderGenBit* pGenBit = pShaderGen->m_BitMask[i];
if (pGenBit->m_Flags & SHGF_HIDDEN)
{
continue;
}
if (!pGenBit->m_ParamProp.empty())
{
IVariable* pVar = pBlock->FindVariable(pGenBit->m_ParamProp.c_str());
if (!pVar)
{
continue;
}
bool bFlagOn = false;
pVar->Get(bFlagOn);
if (bFlagOn)
{
nGenMask |= pGenBit->m_Mask;
}
}
}
return nGenMask;
}
}
@@ -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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include "Material.h"
namespace MaterialHelpers
{
//////////////////////////////////////////////////////////////////////////
//! Get public parameters of material in variable block.
CVarBlock* GetPublicVars(SInputShaderResources& pShaderResources);
//! Sets variable block of public shader parameters.
//! VarBlock must be in same format as returned by GetPublicVars().
void SetPublicVars(CVarBlock* pPublicVars, SInputShaderResources& pInputShaderResources);
void SetPublicVars(CVarBlock* pPublicVars, SInputShaderResources& pInputShaderResources, IRenderShaderResources* pRenderShaderResources, IShader* pShader);
//////////////////////////////////////////////////////////////////////////
CVarBlock* GetShaderGenParamsVars(IShader* pShader, uint64 nShaderGenMask);
uint64 SetShaderGenParamsVars(IShader* pShader, CVarBlock* pBlock);
//////////////////////////////////////////////////////////////////////////
// [Shader System TO DO] change the usage of these functions to retrieve by slot name
inline EEfResTextures FindTexSlot(const char* texName) { return GetIEditor()->Get3DEngine()->GetMaterialHelpers().FindTexSlot(texName); }
inline const char* FindTexName(EEfResTextures texSlot) { return GetIEditor()->Get3DEngine()->GetMaterialHelpers().FindTexName(texSlot); }
inline const char* LookupTexName(EEfResTextures texSlot) { return GetIEditor()->Get3DEngine()->GetMaterialHelpers().LookupTexName(texSlot); }
inline const char* LookupTexDesc(EEfResTextures texSlot) { return GetIEditor()->Get3DEngine()->GetMaterialHelpers().LookupTexDesc(texSlot); }
//--------------------------------------------------------------------------
// Adjustable means that the slot is not virtual, i.e. using a sub-channel from another
// slot (for example - smoothness that uses the normal's alpha)
inline bool IsAdjustableTexSlot(EEfResTextures texSlot) { return GetIEditor()->Get3DEngine()->GetMaterialHelpers().IsAdjustableTexSlot(texSlot); }
//////////////////////////////////////////////////////////////////////////
inline void SetTexModFromXml(SEfTexModificator& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetTexModFromXml(pShaderResources, node); }
inline void SetXmlFromTexMod(const SEfTexModificator& pShaderResources, XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetXmlFromTexMod(pShaderResources, node); }
//////////////////////////////////////////////////////////////////////////
inline void SetTexturesFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetTexturesFromXml(pShaderResources, node); }
inline void SetXmlFromTextures( SInputShaderResources& pShaderResources, XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetXmlFromTextures(pShaderResources, node); }
//////////////////////////////////////////////////////////////////////////
inline void SetVertexDeformFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetVertexDeformFromXml(pShaderResources, node); }
inline void SetXmlFromVertexDeform(const SInputShaderResources& pShaderResources, XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetXmlFromVertexDeform(pShaderResources, node); }
//////////////////////////////////////////////////////////////////////////
inline void SetLightingFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetLightingFromXml(pShaderResources, node); }
inline void SetXmlFromLighting(const SInputShaderResources& pShaderResources, XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetXmlFromLighting(pShaderResources, node); }
//////////////////////////////////////////////////////////////////////////
inline void SetShaderParamsFromXml(SInputShaderResources& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetShaderParamsFromXml(pShaderResources, node); }
inline void SetXmlFromShaderParams(const SInputShaderResources& pShaderResources, XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().SetXmlFromShaderParams(pShaderResources, node); }
//////////////////////////////////////////////////////////////////////////
inline void MigrateXmlLegacyData(SInputShaderResources& pShaderResources, const XmlNodeRef& node) { GetIEditor()->Get3DEngine()->GetMaterialHelpers().MigrateXmlLegacyData(pShaderResources, node); }
}
@@ -1,834 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "MaterialImageListCtrl.h"
// Qt
#include <QMenu>
// Editor
#include "Material.h"
#include "MaterialManager.h"
#include "MaterialPreviewModelView.h"
#include "MaterialBrowser.h"
#include "Util/Image.h"
#define ME_BG_TEXTURE "Materials/Stripes.dds"
#define MATERIAL_EDITOR_SPHERE_MODEL_FILE "Objects/MtlSphere.cgf"
#define MATERIAL_EDITOR_SPHERE_CAMERA_RADIUS 1.6f
#define MATERIAL_EDITOR_SPHERE_CAMERA_FROM_DIRECTION Vec3(0.1f, -1.0f, -0.1f)
#define MATERIAL_EDITOR_BOX_MODEL_FILE "Objects/MtlBox.cgf"
#define MATERIAL_EDITOR_BOX_CAMERA_RADIUS 2.0f
#define MATERIAL_EDITOR_BOX_CAMERA_FROM_DIRECTION Vec3(0.75f, -0.75f, -0.5f)
#define MATERIAL_EDITOR_TEAPOT_MODEL_FILE "Objects/MtlTeapot.cgf"
#define MATERIAL_EDITOR_TEAPOT_CAMERA_RADIUS 1.6f
#define MATERIAL_EDITOR_TEAPOT_CAMERA_FROM_DIRECTION Vec3(0.1f, -0.75f, -0.25f)
#define MATERIAL_EDITOR_PLANE_MODEL_FILE "Objects/MtlPlane.cgf"
#define MATERIAL_EDITOR_PLANE_CAMERA_RADIUS 1.6f
#define MATERIAL_EDITOR_PLANE_CAMERA_FROM_DIRECTION Vec3(-0.5f, 0.5f, -0.5f)
#define MATERIAL_EDITOR_SWATCH_MODEL_FILE "Objects/MtlSwatch.cgf"
#define MATERIAL_EDITOR_SWATCH_CAMERA_RADIUS 1.0f
#define MATERIAL_EDITOR_SWATCH_CAMERA_FROM_DIRECTION Vec3(0.0f, 0.0f, -1.0f)
_smart_ptr<CMaterial> ResolveTerrainLayerPreviewMaterial(_smart_ptr<CMaterial> material, _smart_ptr<CMaterial> pMatPreview)
{
if (!QString::compare(material->GetShaderName(), "Terrain.Layer"))
{
XmlNodeRef node = XmlHelpers::CreateXmlNode("Material");
CBaseLibraryItem::SerializeContext ctx(node, false);
material->Serialize(ctx);
if (!pMatPreview)
{
int flags = 0;
if (node->getAttr("MtlFlags", flags))
{
flags |= MTL_FLAG_UIMATERIAL;
node->setAttr("MtlFlags", flags);
}
pMatPreview = GetIEditor()->GetMaterialManager()->CreateMaterial("_NewPreview_", node);
}
else
{
CBaseLibraryItem::SerializeContext ctx2(node, true);
pMatPreview->Serialize(ctx2);
}
pMatPreview->SetShaderName("Illum");
pMatPreview->Update();
return pMatPreview;
}
else
{
return material;
}
}
struct QMaterialImageListModel::Item
{
QImage image;
void* pUserData;
QPoint position;
QSize size;
_smart_ptr<CMaterial> pMaterial;
QStringList vVisibleTextures;
};
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::OnCreate()
{
// m_largePreviewCtrl is used to draw the 3D preview for the selected material
m_largePreviewCtrl.reset(new MaterialPreviewModelView(this));
m_largePreviewCtrl->hide();
// m_renderCtrl is used to draw all the sub-materials
m_renderCtrl.reset(new MaterialPreviewModelView(this, false /* disable idle updates since this is only used to create the preview list images */));
m_renderCtrl->UnSetFlag(CPreviewModelView::PreviewModelViewFlag::SHOW_GRID);
m_renderCtrl->UnSetFlag(CPreviewModelView::PreviewModelViewFlag::SHOW_GRID_AXIS);
if (gEnv->pSystem)
{
gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(this);
}
// m_resizeTimer is used to stall updateGeometries being called via resizeEvents until RESIZE_TIMEOUT ms after resizing
// This prevents an Editor freeze caused by constant resizing of the Material Editor when viewing
// a high sub-material count material (LY-58389)
m_resizeTimer = new QTimer(this);
connect(m_resizeTimer, &QTimer::timeout, this, &CMaterialImageListCtrl::ResizeTimeout);
}
void CMaterialImageListCtrl::resizeEvent([[maybe_unused]] QResizeEvent* event)
{
m_resizeTimer->stop();
m_resizeTimer->start(RESIZE_TIMEOUT);
}
void CMaterialImageListCtrl::ResizeTimeout()
{
m_resizeTimer->stop();
updateGeometries();
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::OnDestroy()
{
if (gEnv->pSystem)
{
gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(this);
}
}
//////////////////////////////////////////////////////////////////////////
CMaterialImageListCtrl::CMaterialImageListCtrl(QWidget* parent)
: CImageListCtrl(parent)
{
OnCreate();
}
//////////////////////////////////////////////////////////////////////////
CMaterialImageListCtrl::~CMaterialImageListCtrl()
{
OnDestroy();
}
//////////////////////////////////////////////////////////////////////////
QModelIndex QMaterialImageListModel::AddMaterial(CMaterial* pMaterial, void* pUserData)
{
Item* pItem = new Item;
pItem->pMaterial = pMaterial;
pItem->pUserData = pUserData;
pMaterial->GetAnyTextureFilenames(pItem->vVisibleTextures);
const int row = m_items.count();
beginInsertRows(QModelIndex(), row, row);
m_items.insert(row, pItem);
endInsertRows();
return index(row, 0);
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::SetMaterial(int nItemIndex, CMaterial* pMaterial, void* pUserData)
{
assert(nItemIndex <= (int)m_items.size());
Item* pItem = m_items.at(nItemIndex);
pItem->vVisibleTextures.clear();
pItem->pMaterial = pMaterial;
pItem->pUserData = pUserData;
pMaterial->GetAnyTextureFilenames(pItem->vVisibleTextures);
pItem->image = QImage();
QModelIndex idx = index(nItemIndex, 0);
emit dataChanged(idx, idx, QVector<int>() << Qt::DisplayRole << Qt::DecorationRole);
}
//////////////////////////////////////////////////////////////////////////
QModelIndex QMaterialImageListModel::FindMaterial(CMaterial* const pMaterial)
{
for (int i = 0; i < m_items.count(); i++)
{
Item* item = m_items[i];
if (pMaterial == item->pMaterial)
{
return index(i, 0);
}
}
return QModelIndex();
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::SelectMaterial(CMaterial* pMaterial)
{
// Force the material to load the highest resolution textures
pMaterial->GetMatInfo()->DisableTextureStreaming();
selectionModel()->clearSelection();
QMaterialImageListModel* materialModel = qobject_cast<QMaterialImageListModel*>(model());
Q_ASSERT(materialModel);
QModelIndex index = materialModel->FindMaterial(pMaterial);
if (index.isValid())
{
selectionModel()->select(index, QItemSelectionModel::SelectCurrent);
m_largePreviewMaterial = pMaterial;
}
else
{
// If the parent material was selected, set the first sub-material as the large preview's material so it has something to render
if (pMaterial->GetSubMaterialCount() > 0)
{
m_largePreviewMaterial = pMaterial->GetSubMaterial(0);
}
}
GenerateAllImages();
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::InvalidateMaterial(CMaterial* pMaterial)
{
QModelIndex idx = FindMaterial(pMaterial);
Item* pItem = ItemFromIndex(idx);
if ((pItem) && (m_renderCtrl))
{
if (pMaterial)
{
// Ensure the full resolution textures are loaded for the material editor
pMaterial->GetMatInfo()->DisableTextureStreaming();
}
pItem->vVisibleTextures.clear();
pMaterial->GetAnyTextureFilenames(pItem->vVisibleTextures);
pItem->image = QImage();
GenerateImage(pItem);
emit dataChanged(idx, idx, QVector<int>() << Qt::DecorationRole);
}
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::DeleteAllItems()
{
if (m_renderCtrl)
{
m_renderCtrl->SetMaterial(nullptr);
}
beginResetModel();
qDeleteAll(m_items);
m_items.clear();
endResetModel();
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::GenerateImage(Item* pItem)
{
// Make a bitmap from image.
Q_ASSERT(pItem);
if (!m_renderCtrl || !pItem->size.isValid())
{
return;
}
if (pItem->image.size() == pItem->size)
{
return;
}
Item* pMtlItem = pItem;
CImageEx image;
bool bPreview = false;
if (pMtlItem->pMaterial)
{
if (!(pMtlItem->pMaterial->GetFlags() & MTL_FLAG_NOPREVIEW))
{
if (!m_renderCtrl->GetStaticModel())
{
AZ_Warning("Material Editor", false, "Preview renderer has no object loaded!");
return;
}
// keep m_renderCtrl off screen, but visible
m_renderCtrl->setGeometry(QRect(-QPoint(pItem->size.width(), pItem->size.height()), pItem->size));
_smart_ptr<CMaterial> matPreview = ResolveTerrainLayerPreviewMaterial(pItem->pMaterial, m_pMatPreview);
m_renderCtrl->SetMaterial(matPreview->GetMatInfo());
m_renderCtrl->GetImageOffscreen(image, pMtlItem->size);
}
bPreview = true;
}
if (!bPreview)
{
image.Allocate(pItem->size.width(), pItem->size.height());
image.Clear();
}
pItem->image = QImage(image.GetWidth(), image.GetHeight(), QImage::Format_RGB32);
memcpy(pItem->image.bits(), image.GetData(), image.GetSize());
}
#define MENU_USE_DEFAULT 1
#define MENU_USE_BOX 2
#define MENU_USE_PLANE 3
#define MENU_USE_SPHERE 4
#define MENU_USE_TEAPOT 5
#define MENU_BG_BLACK 6
#define MENU_BG_GRAY 7
#define MENU_BG_WHITE 8
#define MENU_BG_TEXTURE 9
#define MENU_USE_BACKLIGHT 10
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::contextMenuEvent(QContextMenuEvent* event)
{
QAction* action;
QMenu menu;
action = menu.addAction(tr("Use Default Object"));
action->setData(ModelDefault);
action->setCheckable(true);
action->setChecked(m_modelType == ModelType::Default);
action = menu.addAction(tr("Use Plane"));
action->setData(ModelPlane);
action->setCheckable(true);
action->setChecked(m_modelType == ModelType::Plane);
action = menu.addAction(tr("Use Box"));
action->setData(ModelBox);
action->setCheckable(true);
action->setChecked(m_modelType == ModelType::Box);
action = menu.addAction(tr("Use Sphere"));
action->setData(ModelSphere);
action->setCheckable(true);
action->setChecked(m_modelType == ModelType::Sphere);
action = menu.addAction(tr("Use Teapot"));
action->setData(ModelTeapot);
action->setCheckable(true);
action->setChecked(m_modelType == ModelType::Teapot);
menu.addSeparator();
// If there is a currently selected material
if (m_materialBrowserWidget && m_largePreviewMaterial)
{
// Add context menu actions that are common to both the material browser and the preview swatches
m_materialBrowserWidget->AddContextMenuActionsSingleSelection(menu, m_largePreviewMaterial);
}
action = menu.exec(mapToGlobal(event->pos()));
if (!action)
{
return;
}
int cmd = action->data().toInt();
switch (cmd)
{
case ModelDefault:
m_modelType = ModelType::Default;
LoadModel();
break;
case ModelPlane:
m_modelType = ModelType::Plane;
LoadModel();
break;
case ModelBox:
m_modelType = ModelType::Box;
LoadModel();
break;
case ModelSphere:
m_modelType = ModelType::Sphere;
LoadModel();
break;
case ModelTeapot:
m_modelType = ModelType::Teapot;
LoadModel();
break;
default:
// If there is a currently selected material
if (m_materialBrowserWidget && m_largePreviewMaterial)
{
// Handle context menu actions that are common to both the material browser and the preview swatches
m_materialBrowserWidget->OnContextMenuAction(cmd, m_largePreviewMaterial);
}
break;
}
QMaterialImageListModel* materialModel =
qobject_cast<QMaterialImageListModel*>(model());
Q_ASSERT(materialModel);
materialModel->GenerateImages();
update();
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::LoadModel()
{
switch (m_modelType)
{
case ModelType::Default:
case ModelType::Sphere:
m_largePreviewCtrl->LoadModelFile(MATERIAL_EDITOR_SPHERE_MODEL_FILE);
m_largePreviewCtrl->SetCameraLookAt(MATERIAL_EDITOR_SPHERE_CAMERA_RADIUS, MATERIAL_EDITOR_SPHERE_CAMERA_FROM_DIRECTION);
break;
case ModelType::Box:
m_largePreviewCtrl->LoadModelFile(MATERIAL_EDITOR_BOX_MODEL_FILE);
m_largePreviewCtrl->SetCameraLookAt(MATERIAL_EDITOR_BOX_CAMERA_RADIUS, MATERIAL_EDITOR_BOX_CAMERA_FROM_DIRECTION);
break;
case ModelType::Teapot:
m_largePreviewCtrl->LoadModelFile(MATERIAL_EDITOR_TEAPOT_MODEL_FILE);
m_largePreviewCtrl->SetCameraLookAt(MATERIAL_EDITOR_TEAPOT_CAMERA_RADIUS, MATERIAL_EDITOR_TEAPOT_CAMERA_FROM_DIRECTION);
break;
case ModelType::Plane:
m_largePreviewCtrl->LoadModelFile(MATERIAL_EDITOR_PLANE_MODEL_FILE);
m_largePreviewCtrl->SetCameraLookAt(MATERIAL_EDITOR_PLANE_CAMERA_RADIUS, MATERIAL_EDITOR_PLANE_CAMERA_FROM_DIRECTION);
break;
}
GenerateAllImages();
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::updateGeometries()
{
ClearItemGeometries();
m_updatingGeometries = true;
if (!model())
{
return;
}
const int rowCount = model()->rowCount();
if (!rowCount)
{
m_largePreviewCtrl->hide();
m_largePreviewMaterial = nullptr;
return;
}
m_largePreviewCtrl->setParent(nullptr);
m_largePreviewCtrl->setParent(this);
m_largePreviewCtrl->show();
const int bwidth = BorderSize().width();
const int bheight = BorderSize().height();
m_largePreviewCtrl->move(bwidth, bheight);
QRect rc = viewport()->contentsRect()
.adjusted(bwidth, bheight, -bwidth, -bheight);
int cy = rc.height();
// Preview item is big.
if (model()->rowCount() > 0)
{
QSize size(cy, rc.height());
m_largePreviewCtrl->SetSize(size);
m_largePreviewCtrl->resize(size);
rc.setLeft(rc.left() + cy + bwidth * 2);
m_largePreviewCtrl->show();
}
int cx = rc.width() - bwidth;
int itemSize = cy;
// Adjust all other bitmaps as tight as possible.
int numItems = model()->rowCount();
int div = 0;
for (div = 1; div < 1000 && itemSize > 0; div++)
{
int nX = cx / (itemSize + 2);
if (nX >= numItems)
{
break;
}
if (nX > 0)
{
int nY = numItems / nX + 1;
if (nY * (itemSize + 2) < cy)
{
//itemSize = itemSize -= 2;
break;
}
}
itemSize = itemSize -= 2;
}
if (itemSize < 0)
{
itemSize = 0;
}
QPoint pos(rc.topLeft());
const QSize size(itemSize, itemSize);
m_renderCtrl->SetSize(size);
for (int row = 0; row < numItems; ++row)
{
QModelIndex index = model()->index(row, 0);
SetItemGeometry(index, QRect(pos, size));
model()->setData(index, pos, QMaterialImageListModel::PositionRole);
model()->setData(index, size, Qt::SizeHintRole);
pos.rx() += itemSize + 2;
if (pos.rx() + itemSize >= rc.right())
{
pos.rx() = rc.left();
pos.ry() += itemSize + 2;
}
}
m_updatingGeometries = false;
update();
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::setModel(QAbstractItemModel* model)
{
QMaterialImageListModel* materialModel = qobject_cast<QMaterialImageListModel*>(model);
if (materialModel)
{
materialModel->SetPreviewModelCtrl(m_renderCtrl.data());
}
CImageListCtrl::setModel(model);
auto delegate = qobject_cast<QImageListDelegate*>(itemDelegate());
// in case the delegate misses a pixmap we can generate it (done only once not at every painting)
connect(delegate, SIGNAL(invalidPixmapGenerated(const QModelIndex&)), materialModel, SLOT(GenerateImage(const QModelIndex&)));
connect(model, &QAbstractItemModel::dataChanged, this, &CMaterialImageListCtrl::ModelDataChanged);
}
void CMaterialImageListCtrl::ModelDataChanged(const QModelIndex& index)
{
// Prevent the hundreads of resize calls done in a row
// to trigger a new image computation that we already have
if (m_updatingGeometries)
{
return;
}
GenerateImage(index);
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::showEvent(QShowEvent* event)
{
CImageListCtrl::showEvent(event);
if (!m_largePreviewCtrl->GetStaticModel())
{
LoadModel();
}
if (!m_renderCtrl->GetStaticModel())
{
m_renderCtrl->LoadModelFile(MATERIAL_EDITOR_SWATCH_MODEL_FILE);
m_renderCtrl->SetCameraLookAt(MATERIAL_EDITOR_SWATCH_CAMERA_RADIUS, MATERIAL_EDITOR_SWATCH_CAMERA_FROM_DIRECTION);
}
}
//////////////////////////////////////////////////////////////////////////
void CMaterialImageListCtrl::OnSystemEvent(ESystemEvent event, UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam)
{
switch (event)
{
// Toggle visibility of this control whenever the main editor window has a change of focus.
case ESYSTEM_EVENT_CHANGE_FOCUS:
{
setAttribute(Qt::WA_WState_Visible, (wparam != 0));
break;
}
}
;
}
void CMaterialImageListCtrl::UpdateLargePreview()
{
if (m_largePreviewMaterial)
{
m_largePreviewCtrl->SetMaterial(ResolveTerrainLayerPreviewMaterial(m_largePreviewMaterial, m_tempTerrainMaterial)->GetMatInfo());
m_largePreviewCtrl->show();
m_largePreviewCtrl->update();
}
}
void CMaterialImageListCtrl::GenerateImage(const QModelIndex& index)
{
QMaterialImageListModel* materialModel =
qobject_cast<QMaterialImageListModel*>(model());
Q_ASSERT(materialModel);
if (m_largePreviewMaterial == materialModel->MaterialFromIndex(index))
{
UpdateLargePreview();
}
materialModel->SetPreviewModelCtrl(m_renderCtrl.data());
materialModel->GenerateImage(index);
update();
}
void CMaterialImageListCtrl::GenerateAllImages()
{
QMaterialImageListModel* materialModel =
qobject_cast<QMaterialImageListModel*>(model());
Q_ASSERT(materialModel);
UpdateLargePreview();
materialModel->SetPreviewModelCtrl(m_renderCtrl.data());
materialModel->GenerateImages();
update();
}
//////////////////////////////////////////////////////////////////////////
QMaterialImageListModel::QMaterialImageListModel(QObject* parent)
: QAbstractListModel(parent)
, m_renderCtrl(nullptr)
{
BusConnect(AZ_CRC("dds", 0x780234cb));
}
//////////////////////////////////////////////////////////////////////////
QMaterialImageListModel::~QMaterialImageListModel()
{
BusDisconnect();
qDeleteAll(m_items);
}
//////////////////////////////////////////////////////////////////////////
MaterialPreviewModelView* QMaterialImageListModel::PreviewModelCtrl() const
{
return m_renderCtrl;
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::SetPreviewModelCtrl(MaterialPreviewModelView* ctrl)
{
if (m_renderCtrl)
{
disconnect(m_renderCtrl, &MaterialPreviewModelView::destroyed,
this, &QMaterialImageListModel::ClearPreviewModelCtrl);
}
m_renderCtrl = ctrl;
if (m_renderCtrl)
{
connect(m_renderCtrl, &MaterialPreviewModelView::destroyed,
this, &QMaterialImageListModel::ClearPreviewModelCtrl);
}
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::ClearPreviewModelCtrl()
{
m_renderCtrl = nullptr;
}
//////////////////////////////////////////////////////////////////////////
int QMaterialImageListModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid())
{
return 0;
}
return m_items.count();
}
//////////////////////////////////////////////////////////////////////////
QVariant QMaterialImageListModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
Item* pItem = m_items.at(index.row());
Q_ASSERT(pItem);
switch (role)
{
case Qt::DisplayRole:
return pItem->pMaterial->GetShortName();
case Qt::DecorationRole:
return QPixmap::fromImage(pItem->image);
case PositionRole:
return pItem->position;
case Qt::SizeHintRole:
return pItem->size;
default:
break;
}
return QVariant();
}
//////////////////////////////////////////////////////////////////////////
bool QMaterialImageListModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid())
{
return false;
}
Item* pItem = ItemFromIndex(index);
if (!pItem)
{
return false;
}
if (Qt::SizeHintRole == role)
{
pItem->size = value.toSize();
emit dataChanged(index, index, QVector<int>() << Qt::DecorationRole << Qt::SizeHintRole);
return true;
}
if (PositionRole == role)
{
pItem->position = value.toPoint();
}
return false;
}
//////////////////////////////////////////////////////////////////////////
Qt::ItemFlags QMaterialImageListModel::flags(const QModelIndex& index) const
{
return QAbstractListModel::flags(index);
}
//////////////////////////////////////////////////////////////////////////
CMaterial* QMaterialImageListModel::MaterialFromIndex(QModelIndex index) const
{
Item* pItem = ItemFromIndex(index);
if (!pItem)
{
return nullptr;
}
return pItem->pMaterial;
}
//////////////////////////////////////////////////////////////////////////
void* QMaterialImageListModel::UserDataFromIndex(QModelIndex index) const
{
Item* pItem = ItemFromIndex(index);
if (!pItem)
{
return nullptr;
}
return pItem->pUserData;
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::GenerateImages()
{
if ((!m_renderCtrl) || (m_items.isEmpty()))
{
return;
}
for (Item* materialImageListItem : m_items)
{
GenerateImage(materialImageListItem);
}
}
void QMaterialImageListModel::GenerateImage(const QModelIndex& index)
{
if ((!m_renderCtrl) || (m_items.isEmpty()))
{
return;
}
GenerateImage(ItemFromIndex(index));
}
//////////////////////////////////////////////////////////////////////////
QMaterialImageListModel::Item* QMaterialImageListModel::ItemFromIndex(QModelIndex index) const
{
if (!index.isValid())
{
return nullptr;
}
return m_items.at(index.row());
}
//////////////////////////////////////////////////////////////////////////
void QMaterialImageListModel::OnFileChanged(AZStd::string assetPath)
{
const int rowCount = m_items.count();
// update all previews who's texture(s) changed
for (int row = 0; row < rowCount; ++row)
{
Item* pItem = m_items.at(row);
QStringList::const_iterator textureIt = std::find(pItem->vVisibleTextures.begin(), pItem->vVisibleTextures.end(), assetPath.c_str());
if (textureIt != pItem->vVisibleTextures.end())
{
pItem->image = QImage();
QModelIndex idx = index(row, 0);
emit dataChanged(idx, idx, QVector<int>() << Qt::DecorationRole);
}
}
}
#include <Material/moc_MaterialImageListCtrl.cpp>
@@ -1,164 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALIMAGELISTCTRL_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIALIMAGELISTCTRL_H
#pragma once
#if !defined(Q_MOC_RUN)
#include "Controls/ImageListCtrl.h"
#include <QAbstractListModel>
#include "Material.h"
#include "IRenderer.h" // IAsyncTextureCompileListener
#include "IResourceCompilerHelper.h"
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <QScopedPointer>
#include <QPointer>
#endif
class MaterialPreviewModelView;
class MaterialBrowserWidget;
//////////////////////////////////////////////////////////////////////////
class CMaterialImageListCtrl
: public CImageListCtrl
, public ISystemEventListener
{
Q_OBJECT
public:
enum class ModelType
{
Default,
Box,
Sphere,
Teapot,
Plane
};
enum MenuAction
{
ModelDefault = 0,
ModelPlane,
ModelBox,
ModelSphere,
ModelTeapot,
// Context menu actions that are common to both the material browser and the preview swatches
// are handled by the same switch statement, so they need to be unique. This sets the starting point for the common actions
MaterialBrowserWidgetActionsStart
};
CMaterialImageListCtrl(QWidget* parent = nullptr);
~CMaterialImageListCtrl();
void setModel(QAbstractItemModel* model) override;
void EnableAutoRefresh(bool autoRefreshState, unsigned int refreshInterval);
void SelectMaterial(CMaterial* pMaterial);
void LoadModel();
void SetMaterialBrowserWidget(MaterialBrowserWidget* materialBrowserWidget){ m_materialBrowserWidget = materialBrowserWidget; }
// ISystemEventListener
// Due to the material editor working on a ProcessEvents -> Timer based system, rather than the OnIdle update event loops
// that the other editor windows use, make sure that when the editor loses focus that the Material Editor itself loses focus.
// This will pause updates/renderings in the material editor when it does not have focus.
// This prevents certain materials from re-creating themselves and eventually overflowing a few resource buffers.
// The main window cleans up those resources during its main update, which is bypassed when the window does not have focus.
virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam);
// ~ISystemEventListener
// Override resizeEvent and use this const to rate limit it such that it only fires RESIZE_TIMEOUT ms after resizing stops
static const int RESIZE_TIMEOUT = 100;
void resizeEvent(QResizeEvent* event) override;
public slots:
void ModelDataChanged(const QModelIndex& index);
void ResizeTimeout();
protected:
void OnCreate();
void OnDestroy();
void contextMenuEvent(QContextMenuEvent* event) override;
void showEvent(QShowEvent* event) override;
void updateGeometries() override;
private:
void GenerateImage(const QModelIndex& index);
void GenerateAllImages();
void UpdateLargePreview();
QScopedPointer<MaterialPreviewModelView> m_largePreviewCtrl; // Used to draw the main 3D preview viewport for the selected sub-material
_smart_ptr<CMaterial> m_largePreviewMaterial;
_smart_ptr<CMaterial> m_tempTerrainMaterial;
QScopedPointer<MaterialPreviewModelView> m_renderCtrl; // Used to draw the swatches for all the sub-materials
int m_nColor;
bool m_updatingGeometries = false;
ModelType m_modelType = ModelType::Default;
MaterialBrowserWidget* m_materialBrowserWidget;
QTimer* m_resizeTimer; // Used to stall a resizeEvent from firing until RESIZE_TIMEOUT ms have passed since resizing stopped
};
class QMaterialImageListModel
: public QAbstractListModel
, public AzFramework::LegacyAssetEventBus::Handler
{
struct Item;
Q_OBJECT
public:
enum CustomRoles
{
PositionRole = Qt::UserRole
};
QMaterialImageListModel(QObject* parent = nullptr);
~QMaterialImageListModel();
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
QModelIndex AddMaterial(CMaterial* pMaterial, void* pUserData = nullptr);
void SetMaterial(int nItemIndex, CMaterial* pMaterial, void* pUserData = nullptr);
QModelIndex FindMaterial(CMaterial* pMaterial);
void InvalidateMaterial(CMaterial* pMaterial);
void DeleteAllItems();
MaterialPreviewModelView* PreviewModelCtrl() const;
void SetPreviewModelCtrl(MaterialPreviewModelView* ctrl);
CMaterial* MaterialFromIndex(QModelIndex index) const;
void* UserDataFromIndex(QModelIndex index) const;
public slots:
void GenerateImages();
void GenerateImage(const QModelIndex& index);
protected:
void GenerateImage(Item* pItem);
Item* ItemFromIndex(QModelIndex index) const;
private slots:
void ClearPreviewModelCtrl();
private:
void OnFileChanged(AZStd::string assetPath) override;
private:
_smart_ptr<CMaterial> m_pMatPreview;
QPointer<MaterialPreviewModelView> m_renderCtrl;
QVector<Item*> m_items;
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALIMAGELISTCTRL_H
@@ -1,151 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "EditorDefs.h"
#include "MaterialLibrary.h"
// Editor
#include "BaseLibraryItem.h"
//////////////////////////////////////////////////////////////////////////
// CMaterialLibrary implementation.
//////////////////////////////////////////////////////////////////////////
bool CMaterialLibrary::Save()
{
return SaveLibrary("MaterialLibrary");
}
//////////////////////////////////////////////////////////////////////////
bool CMaterialLibrary::Load(const QString& filename)
{
if (filename.isEmpty())
{
return false;
}
SetFilename(filename);
XmlNodeRef root = XmlHelpers::LoadXmlFromFile(filename.toUtf8().data());
if (!root)
{
return false;
}
Serialize(root, true);
return true;
}
//////////////////////////////////////////////////////////////////////////
void CMaterialLibrary::Serialize([[maybe_unused]] XmlNodeRef& root, [[maybe_unused]] bool bLoading)
{
/*
if (bLoading)
{
// Loading.
CString name = GetName();
root->getAttr( "Name",name );
SetName( name );
for (int i = 0; i < root->getChildCount(); i++)
{
XmlNodeRef itemNode = root->getChild(i);
CMaterial *material = new CMaterial(itemNode->getAttr("Name"));
AddItem( material );
CBaseLibraryItem::SerializeContext ctx( itemNode,bLoading );
material->Serialize( ctx );
}
SetModified(false);
}
else
{
// Saving.
root->setAttr( "Name",GetName() );
root->setAttr( "SandboxVersion",(const char*)GetIEditor()->GetFileVersion().ToFullString() );
// Serialize prototypes.
for (int i = 0; i < GetItemCount(); i++)
{
CMaterial *pMtl = (CMaterial*)GetItem(i);
// Save materials with parents under thier parent xml node.
if (pMtl->GetParent())
continue;
XmlNodeRef itemNode = root->newChild( "Material" );
CBaseLibraryItem::SerializeContext ctx( itemNode,bLoading );
GetItem(i)->Serialize( ctx );
}
}
*/
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void CMaterialLibrary::AddItem(IDataBaseItem* item, bool bRegister)
{
CBaseLibraryItem* pLibItem = (CBaseLibraryItem*)item;
// Check if item is already assigned to this library.
if (pLibItem->GetLibrary() != this)
{
pLibItem->SetLibrary(this);
if (bRegister)
{
m_pManager->RegisterItem(pLibItem);
}
m_items.push_back(pLibItem);
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CMaterialLibrary::GetItem(int index)
{
assert(index >= 0 && index < m_items.size());
return m_items[index];
}
//////////////////////////////////////////////////////////////////////////
void CMaterialLibrary::RemoveItem(IDataBaseItem* item)
{
for (int i = 0; i < m_items.size(); i++)
{
if (m_items[i] == item)
{
m_items.erase(m_items.begin() + i);
SetModified();
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
IDataBaseItem* CMaterialLibrary::FindItem(const QString& name)
{
for (int i = 0; i < m_items.size(); i++)
{
if (QString::compare(m_items[i]->GetName(), name, Qt::CaseInsensitive) == 0)
{
return m_items[i];
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
void CMaterialLibrary::RemoveAllItems()
{
AddRef();
for (int i = 0; i < m_items.size(); i++)
{
// Clear library item.
m_items[i]->SetLibrary(NULL);
}
m_items.clear();
Release();
}
@@ -1,47 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALLIBRARY_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIALLIBRARY_H
#pragma once
#include "BaseLibrary.h"
/** Library of prototypes.
*/
class CRYEDIT_API CMaterialLibrary
: public CBaseLibrary
{
public:
CMaterialLibrary(IBaseLibraryManager* pManager)
: CBaseLibrary(pManager) {};
virtual bool Save();
virtual bool Load(const QString& filename);
virtual void Serialize(XmlNodeRef& node, bool bLoading);
//////////////////////////////////////////////////////////////////////////
// CBaseLibrary override.
//////////////////////////////////////////////////////////////////////////
void AddItem(IDataBaseItem* item, bool bRegister = true);
int GetItemCount() const { return m_items.size(); }
IDataBaseItem* GetItem(int index);
void RemoveItem(IDataBaseItem* item);
void RemoveAllItems();
IDataBaseItem* FindItem(const QString& name);
private:
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
std::vector<CBaseLibraryItem*> m_items;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALLIBRARY_H
File diff suppressed because it is too large Load Diff
@@ -1,300 +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.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H
#define CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H
#pragma once
#include "BaseLibraryManager.h"
#include "Material.h"
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
#include <Include/IEditorMaterialManager.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/std/string/wildcard.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
#include <AzCore/std/parallel/mutex.h>
#include <AzCore/std/parallel/binary_semaphore.h>
#include <AzCore/std/parallel/thread.h>
class CMaterial;
class CMaterialLibrary;
class CMaterialHighlighter;
namespace AZ
{
struct Uuid;
}
namespace AzToolsFramework
{
namespace AssetBrowser
{
struct SourceFileOpenerDetails;
typedef AZStd::vector<SourceFileOpenerDetails> SourceFileOpenerList;
}
}
enum EHighlightMode
{
eHighlight_Pick = BIT(0),
eHighlight_Breakable = BIT(1),
eHighlight_NoSurfaceType = BIT(2),
eHighlight_All = 0xFFFFFFFF
};
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
/** Manages all entity prototypes and material libraries.
*/
class CRYEDIT_API CMaterialManager
: public IEditorMaterialManager
, public CBaseLibraryManager
, public IMaterialManagerListener
, protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
, public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler
, public AzFramework::AssetCatalogEventBus::Handler
, public AzToolsFramework::EditorEvents::Bus::Handler
{
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
public:
//! Notification callback.
typedef AZStd::function<void()> NotifyCallback;
CMaterialManager(CRegistrationContext& regCtx);
~CMaterialManager();
void Set3DEngine();
// Clear all prototypes and material libraries.
void ClearAll();
//////////////////////////////////////////////////////////////////////////
// Materials.
//////////////////////////////////////////////////////////////////////////
// Loads material.
CMaterial* LoadMaterial(const QString& sMaterialName, bool bMakeIfNotFound = true);
XmlNodeRef LoadXmlNode(const QString &fullSourcePath, const QString &relativeFilePath);
//! Loads a material, avoiding a call to CMaterialManager::MaterialToFilename if the full path is already known
CMaterial* LoadMaterialWithFullSourcePath(const QString& relativeFilePath, const QString& fullSourcePath, bool makeIfNotFound = true);
virtual CMaterial* LoadMaterial(const char* sMaterialName, bool bMakeIfNotFound = true);
virtual void OnRequestMaterial(_smart_ptr<IMaterial> pMaterial);
// Creates a new material from a xml node.
CMaterial* CreateMaterial(const QString& sMaterialName, const XmlNodeRef& node = XmlNodeRef(), int nMtlFlags = 0, unsigned long nLoadingFlags = 0);
virtual CMaterial* CreateMaterial(const char* sMaterialName, const XmlNodeRef& node = XmlNodeRef(), int nMtlFlags = 0, unsigned long nLoadingFlags = 0);
// Duplicate material and do nothing more.
CMaterial* DuplicateMaterial(const char* newName, CMaterial* pOriginal);
// Delete specified material, erases material file, and unassigns from all objects.
virtual void DeleteMaterial(CMaterial* pMtl);
virtual void RemoveMaterialFromDisk(const char* fileName);
//! Export property manager to game.
void Export(XmlNodeRef& node);
int ExportLib(CMaterialLibrary* pLib, XmlNodeRef& libNode);
virtual void SetSelectedItem(IDataBaseItem* pItem);
void SetCurrentMaterial(CMaterial* pMtl);
//! Get currently active material.
CMaterial* GetCurrentMaterial() const;
void SetCurrentFolder(const QString& folder);
// This material will be highlighted
void SetHighlightedMaterial(CMaterial* pMtl);
void GetHighlightColor(ColorF* color, float* intensity, int flags);
void HighlightedMaterialChanged(CMaterial* pMtl);
// highlightMask is a combination of EHighlightMode flags
void SetHighlightMask(int highlightMask);
int GetHighlightMask() const{ return m_highlightMask; }
void SetMarkedMaterials(const std::vector<_smart_ptr<CMaterial> >& markedMaterials);
void OnLoadShader(CMaterial* pMaterial);
//! Serialize property manager.
virtual void Serialize(XmlNodeRef& node, bool bLoading);
virtual void SaveAllLibs();
//////////////////////////////////////////////////////////////////////////
// IMaterialManagerListener implementation
//////////////////////////////////////////////////////////////////////////
// Called when material manager tries to load a material.
virtual void OnCreateMaterial(_smart_ptr<IMaterial> pMaterial);
virtual void OnDeleteMaterial(_smart_ptr<IMaterial> pMaterial);
virtual bool IsCurrentMaterial(_smart_ptr<IMaterial> pMaterial) const;
//////////////////////////////////////////////////////////////////////////
// Convert filename of material file into the name of the material.
QString FilenameToMaterial(const QString& filename);
// Convert name of the material to the filename.
QString MaterialToFilename(const QString& sMaterialName);
//! Get the full file path of the source material
const AZ::Data::AssetType& GetMaterialAssetType();
//////////////////////////////////////////////////////////////////////////
// Convert 3DEngine IMaterial to Editor's CMaterial pointer.
CMaterial* FromIMaterial(_smart_ptr<IMaterial> pMaterial);
// Open File selection dialog to create a new material.
CMaterial* SelectNewMaterial(int nMtlFlags, const char* sStartPath = NULL);
// Synchronize material between 3dsMax and editor.
void SyncMaterialEditor();
//////////////////////////////////////////////////////////////////////////
void GotoMaterial(CMaterial* pMaterial);
void GotoMaterial(_smart_ptr<IMaterial> pMaterial);
// Gather resources from the game material.
static void GatherResources(_smart_ptr<IMaterial> pMaterial, CUsedResources& resources);
void Command_Create();
void Command_CreateMulti();
void Command_ConvertToMulti();
void Command_Duplicate();
void Command_Merge();
void Command_Delete();
void Command_AssignToSelection();
void Command_ResetSelection();
void Command_SelectAssignedObjects();
void Command_SelectFromObject();
protected:
//////////////////////////////////////////////////////////////////////////////////////////////////////
// protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler
void AddSourceFileOpeners(const char* fullSourceFileName, const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) override;
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
// public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationsBus::Handler
void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry);
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
// AssetCatalogEventBus Functions
void OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) override;
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
// EditorEventsBus Functions
bool SkipEditorStartupUI() override;
//////////////////////////////////////////////////////////////////////////////////////////////////////
void SaveDccMaterial(const AZStd::string& relativeDccMaterialPath);
bool DccMaterialRequiresSave(const AZStd::string& relativeDccMaterialPath, const AZStd::string& fullSourcePath);
void DccMaterialSourceControlCheck(const AZStd::string& relativeDccMaterialPath);
void AddDccMaterialPath(const AZStd::string relativeDccMaterialPath);
void TickSourceControl();
void QueueSourceControlTick();
// Duplicate the source material and set it as a submaterial of the target material at subMaterialIndex. Returns true if successful.
bool DuplicateAsSubMaterialAtIndex(CMaterial* pSourceMaterial, CMaterial* pTargetMaterial, int subMaterialIndex);
// Generates a unique variant of the name of the source material to resolve name collisions with the names of the submaterials in the target material.
void GenerateUniqueSubmaterialName(const CMaterial* pSourceMaterial, const CMaterial* pTargetMaterial, QString& uniqueSubmaterialName) const;
// Open save as dialog for saving materials.
bool SelectSaveMaterial(QString& itemName, QString& fullPath, const char* defaultStartPath);
void OnEditorNotifyEvent(EEditorNotifyEvent event);
virtual CBaseLibraryItem* MakeNewItem();
virtual CBaseLibrary* MakeNewLibrary();
//! Root node where this library will be saved.
virtual QString GetRootNodeName();
//! Path to libraries in this manager.
virtual QString GetLibsPath();
virtual void ReportDuplicateItem(CBaseLibraryItem* pItem, CBaseLibraryItem* pOldItem);
void RegisterCommands(CRegistrationContext& regCtx);
void UpdateHighlightedMaterials();
void AddForHighlighting(CMaterial* pMaterial);
void RemoveFromHighlighting(CMaterial* pMaterial, int mask);
int GetHighlightFlags(CMaterial* pMaterial) const;
// For material syncing with 3dsMax.
void PickPreviewMaterial();
void InitMatSender();
//! Reloads any registered materials that have been modified by the runtime.
void ReloadDirtyMaterials();
protected:
QString m_libsPath;
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
// Currently selected (focused) material, in material browser.
_smart_ptr<CMaterial> m_pCurrentMaterial;
// current selected folder
QString m_currentFolder;
// List of materials selected in material browser tree.
std::vector<_smart_ptr<CMaterial> > m_markedMaterials;
// IMaterial is needed to not let 3Dengine release selected IMaterial
_smart_ptr<IMaterial> m_pCurrentEngineMaterial;
// Paths of .dccmtl that might require saving. They will be fed to
// DccMaterialSourceControlCheck() and if saving is required, they
// will be added to m_dccMaterialSaveBuffer
AZStd::vector<AZStd::string> m_sourceControlBuffer;
AZStd::mutex m_sourceControlBufferMutex;
AZStd::atomic_bool m_sourceControlFunctionQueued;
// Paths of .dccmtl that require saving. These paths have
// gone through DccMaterialSourceControlCheck() and will
// be saved by the dcc material save thread
AZStd::vector<AZStd::string> m_dccMaterialSaveBuffer;
AZStd::mutex m_dccMaterialSaveMutex;
// Material highlighting
_smart_ptr<CMaterial> m_pHighlightMaterial;
CMaterialHighlighter* m_pHighlighter;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
int m_highlightMask;
bool m_bHighlightingMaterial;
// Only begin processing .dccmtl filepaths once editor is ready
// and we can display appropriate error messages
bool m_bEditorUiReady;
// Only report source control error to the user once,
// no need to spam them for every material
bool m_bSourceControlErrorReported;
class CMaterialSender* m_MatSender;
private:
CMaterial* LoadMaterialInternal(const QString &materialNameClear, const QString &fullSourcePath, const QString &relativeFilePath, bool bMakeIfNotFound);
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
AZ::Data::AssetType m_materialAssetType;
AZ::Data::AssetType m_dccMaterialAssetType;
void StartDccMaterialSaveThread();
void DccMaterialSaveThreadFunc();
AZStd::thread m_dccMaterialSaveThread;
AZStd::atomic_bool m_joinThreads;
AZStd::binary_semaphore m_dccMaterialSaveSemaphore;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
};
#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALMANAGER_H
@@ -1,77 +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 "EditorDefs.h"
#include "MaterialPreviewModelView.h"
MaterialPreviewModelView::MaterialPreviewModelView(QWidget* parent, bool enableIdleUpdate)
: CPreviewModelView(parent)
, m_enableIdleUpdate(enableIdleUpdate)
{}
MaterialPreviewModelView::~MaterialPreviewModelView()
{}
void MaterialPreviewModelView::SetCameraLookAt(float fRadiusScale, const Vec3& fromDir)
{
IStatObj* target = GetStaticModel();
if (target)
{
Vec3 dir = fromDir.GetNormalized();
// Calculate the camera matrix
Matrix34 tm = Matrix33::CreateRotationVDir(dir, 0);
Vec3 translation = target->GetAABB().GetCenter() - dir * target->GetAABB().GetRadius() * fRadiusScale;
tm.SetTranslation(translation);
// Convert it to a quaternion and move the viewport's camera
QuatT quat(tm);
CameraMoved(quat, true);
}
}
void MaterialPreviewModelView::SetMaterial(_smart_ptr<IMaterial> material)
{
IStatObj* staticModel = GetStaticModel();
if (staticModel)
{
staticModel->SetMaterial(material);
}
}
void MaterialPreviewModelView::resizeEvent(QResizeEvent* event)
{
if (m_enableIdleUpdate)
{
CPreviewModelView::resizeEvent(event);
}
}
void MaterialPreviewModelView::OnEditorNotifyEvent(EEditorNotifyEvent event)
{
switch (event)
{
case eNotify_OnIdleUpdate:
{
if (m_enableIdleUpdate)
{
Update();
}
break;
}
default:
break;
}
}
@@ -1,35 +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 "PreviewModelView.h"
class MaterialPreviewModelView
: public CPreviewModelView
{
public:
// set enableIdleUpdate to false if you don't want the view to update itself during
// application idle notification (and resize events). That makes sense when this view
// is only used to render into memory bitmaps. Note that the view has to been visible
// for that, but can be somewhere of-screen.
MaterialPreviewModelView(QWidget* parent, bool enableIdleUpdate = true);
virtual ~MaterialPreviewModelView();
void SetCameraLookAt(float fRadiusScale, const Vec3& fromDir);
void SetMaterial(_smart_ptr<IMaterial> material);
void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
protected:
void resizeEvent(QResizeEvent* event) override;
private:
bool m_enableIdleUpdate;
};
File diff suppressed because it is too large Load Diff
@@ -1,34 +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 <Include/SandboxAPI.h>
#include <AzCore/Component/Component.h>
namespace AzToolsFramework
{
//! A component to reflect scriptable commands for materials in the Editor
class MaterialPythonFuncsHandler
: public AZ::Component
{
public:
AZ_COMPONENT(MaterialPythonFuncsHandler, "{E437BCF2-DE71-43E1-A7EC-DD243EB41F0B}")
SANDBOX_API static void Reflect(AZ::ReflectContext* context);
// AZ::Component ...
void Activate() override {}
void Deactivate() override {}
};
} // namespace AzToolsFramework
@@ -1,416 +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 "EditorDefs.h"
//AZCore
#include <AzCore/Math/MathUtils.h>
//CRY
#include <ILogFile.h>
#include <IMaterial.h>
//Editor
#include <Settings.h>
#include <IEditor.h>
#include <IResourceSelectorHost.h>
#include <Util/Variable.h>
#include <Util/VariablePropertyType.h>
#include <QViewport.h>
#include <QViewportSettings.h>
#include <DisplaySettings.h>
//EditorCommon
#include <RenderHelpers/AxisHelper.h>
//Local
#include "PreviewModelView.h"
//QT
#include <qapplication.h>
CPreviewModelView::CPreviewModelView(QWidget* parent)
: QViewport(parent, QViewport::StartupMode_Manual) // Manual since we need to set WA_DontCreateNativeAncestors before QViewport::Startup() creates the internal native window and propagates
, m_Flags(0)
, m_GridColor(150, 150, 150, 40)
, m_BackgroundColor(0.5f, 0.5f, 0.5f)
, m_TimeScale(1.0f)
, m_PlayState(PlayState::NONE)
, m_pStaticModel(nullptr)
, m_PostUpdateCallback(nullptr)
, m_ContextMenuCallback(nullptr)
{
#ifdef Q_OS_MACOS
// Don't propagate the nativeness up, as dockwidgets on macOS don't like it
setAttribute(Qt::WA_DontCreateNativeAncestors);
#endif
Startup();
//////////////////////////////////////////////////////////
//QViewport
AddConsumer(this);
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//IEditorNotifyListener
GetIEditor()->RegisterNotifyListener(this);
//////////////////////////////////////////////////////////
FocusOnScreen();//update the camera ...
SetDefaultFlags();
UpdateSettings();
}
CPreviewModelView::~CPreviewModelView()
{
CRY_ASSERT(GetIEditor());
//////////////////////////////////////////////////////////
//IEditorNotifyListener
GetIEditor()->UnregisterNotifyListener(this);
//////////////////////////////////////////////////////////
ReleaseModel();
}
bool CPreviewModelView::IsFlagSet(PreviewModelViewFlag flag) const
{
CRY_ASSERT(flag < PreviewModelViewFlag::END_POSSIBLE_ITEMS);
return (m_Flags & (1 << static_cast<unsigned int>(flag)));
}
void CPreviewModelView::ToggleFlag(PreviewModelViewFlag flag)
{
CRY_ASSERT(flag < PreviewModelViewFlag::END_POSSIBLE_ITEMS);
if (IsFlagSet(flag))
{
UnSetFlag(flag);
}
else
{
SetFlag(flag);
}
}
void CPreviewModelView::SetFlag(PreviewModelViewFlag flag)
{
CRY_ASSERT(flag < PreviewModelViewFlag::END_POSSIBLE_ITEMS);
m_Flags |= (1 << static_cast<unsigned int>(flag));
}
void CPreviewModelView::UnSetFlag(PreviewModelViewFlag flag)
{
CRY_ASSERT(flag < PreviewModelViewFlag::END_POSSIBLE_ITEMS);
m_Flags &= ~(1 << static_cast<unsigned int>(flag));
}
void CPreviewModelView::ResetPlaybackControls()
{
UnSetFlag(CPreviewModelView::PreviewModelViewFlag::LOOPING_PLAY);
m_TimeScale = 1.0f;
}
void CPreviewModelView::ResetBackgroundColor()
{
SetBackgroundColor(ColorF(0.5f, 0.5f, 0.5f));
}
void CPreviewModelView::ResetGridColor()
{
SetGridColor(ColorF(150, 150, 150, 40));
}
void CPreviewModelView::ResetCamera()
{
FocusOnScreen();
}
void CPreviewModelView::ResetAll()
{
ResetPlaybackControls();
ResetGridColor();
ResetBackgroundColor();
ReleaseModel();
SetDefaultFlags();
}
void CPreviewModelView::SetGridColor(ColorF color)
{
m_GridColor = color;
}
void CPreviewModelView::SetBackgroundColor(ColorF color)
{
m_BackgroundColor = color;
}
void CPreviewModelView::SetPlayState(PlayState state)
{
m_PlayState = state;
}
void CPreviewModelView::SetTimeScale(float scale)
{
m_TimeScale = scale;
}
CPreviewModelView::PlayState CPreviewModelView::GetPlayState() const
{
return m_PlayState;
}
float CPreviewModelView::GetTimeScale() const
{
return m_TimeScale;
}
ColorF CPreviewModelView::GetGridColor() const
{
return m_GridColor;
}
ColorF CPreviewModelView::GetBackgroundColor() const
{
return m_BackgroundColor;
}
void CPreviewModelView::ImportModel()
{
SResourceSelectorContext x;
x.typeName = Prop::GetPropertyTypeToResourceType(ePropertyModel);
QString currPath = m_ModelFilename.toLower();
QString selected = GetIEditor()->GetResourceSelectorHost()->SelectResource(x, currPath);
LoadModelFile(selected);
}
void CPreviewModelView::SetPostUpdateCallback(PostUpdateCallback callback)
{
m_PostUpdateCallback = callback;
}
void CPreviewModelView::SetContextMenuCallback(ContextMenuCallback callback)
{
m_ContextMenuCallback = callback;
}
////////////////////////////////////////////////////////
//QViewportConsumer
void CPreviewModelView::OnViewportRender(const SRenderContext& rc)
{
///UPDATE
UpdateSettings();//Some changes may take effect next frame ...
//External updating ...
if (m_PostUpdateCallback)
{
m_PostUpdateCallback();
}
//RENDER
CRY_ASSERT(rc.renderParams);
CRY_ASSERT(rc.passInfo);
RenderModels(*rc.renderParams, *rc.passInfo);
}
void CPreviewModelView::OnViewportKey([[maybe_unused]] const SKeyEvent& ev)
{
}
void CPreviewModelView::OnViewportMouse([[maybe_unused]] const SMouseEvent& ev)
{
}
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//IEditorNotifyListener
void CPreviewModelView::OnEditorNotifyEvent(EEditorNotifyEvent event)
{
switch (event)
{
case eNotify_OnCloseScene:
{
ResetAll();
break;
}
case eNotify_OnIdleUpdate:
{
Update();
}
break;
default:
break;
}
}
///////////////////////////////////////////////////////
void CPreviewModelView::UpdateSettings()
{
//Update the settings
SViewportSettings allsettings;
allsettings.background.topColor = m_BackgroundColor;
allsettings.background.useGradient = false;
allsettings.grid.showGrid = IsFlagSet(PreviewModelViewFlag::SHOW_GRID);
allsettings.grid.middleColor = m_BackgroundColor;
allsettings.grid.mainColor = m_GridColor;
allsettings.rendering.wireframe = IsFlagSet(PreviewModelViewFlag::DRAW_WIREFRAME);
allsettings.rendering.sunlight = IsFlagSet(PreviewModelViewFlag::ENABLE_TIME_OF_DAY);
allsettings.rendering.fps = false;
// Set zoom speed to 1.0f for better UI workflow, instead of the default 0.1f
allsettings.camera.zoomSpeed = 1.0f;
allsettings.camera.moveSpeed = GetIEditor()->GetEditorSettings()->cameraMoveSpeed;
allsettings.camera.fastMoveMultiplier = GetIEditor()->GetEditorSettings()->cameraFastMoveSpeed;
allsettings.camera.rotationSpeed = GetIEditor()->GetEditorSettings()->cameraRotateSpeed;
allsettings.camera.showViewportOrientation = IsFlagSet(PreviewModelViewFlag::SHOW_GRID_AXIS);
//Set them ...
SetSettings(allsettings);
}
void CPreviewModelView::RenderModels(SRendParams& rendParams, SRenderingPassInfo& passInfo)
{
if (m_pStaticModel)
{
if (IsFlagSet(PreviewModelViewFlag::PRECACHE_MATERIAL))
{
_smart_ptr<IMaterial> pCurMat = m_pStaticModel->GetMaterial();
if (pCurMat)
{
pCurMat->PrecacheMaterial(0.0f, nullptr, true, true);
}
}
m_pStaticModel->Render(rendParams, passInfo);
}
}
void CPreviewModelView::ReleaseModel()
{
m_ModelFilename = "";
SAFE_RELEASE(m_pStaticModel);
}
void CPreviewModelView::SetDefaultFlags()
{
UnSetFlag(PreviewModelViewFlag::SHOW_OVERDRAW);
m_Flags = 0;
SetFlag(PreviewModelViewFlag::SHOW_GRID);
SetFlag(PreviewModelViewFlag::SHOW_GRID_AXIS);
}
void CPreviewModelView::LoadModelFile(const QString& modelFile)
{
//Something to load
if (!modelFile.isEmpty())
{
//Make sure we are not loading the same thing ...
if (m_ModelFilename != modelFile)
{
ReleaseModel();//release any old mesh
QString strFileExt = Path::GetExt(modelFile);
bool isCGF = (QString::compare(strFileExt, CRY_GEOMETRY_FILE_EXT, Qt::CaseInsensitive) == 0);
// NOTE: have to create a local buffer and evaluate the full message here due to calling into another address space to evaluate va_args
// this prevents passing of random data to the log system ... any plugin that does not do it this way is rolling the dice each time.
char buffer[2046];
CRY_ASSERT(GetIEditor());
if (isCGF)
{
CRY_ASSERT(GetIEditor()->Get3DEngine());
// Load object.
m_pStaticModel = GetIEditor()->Get3DEngine()->LoadStatObjUnsafeManualRef(modelFile.toUtf8().data(), nullptr, nullptr, false);
if (m_pStaticModel)
{
m_pStaticModel->AddRef();
}
else
{
CRY_ASSERT(GetIEditor()->GetLogFile());
azsprintf(buffer, "Loading of geometry object %s failed.", modelFile.toUtf8().data());
GetIEditor()->GetLogFile()->Warning(buffer);
}
}
else
{
CRY_ASSERT(GetIEditor()->GetLogFile());
azsprintf(buffer, "Unknown model file (%s) attempting to be loaded.", modelFile.toUtf8().data());
GetIEditor()->GetLogFile()->Warning(buffer);
}
//if something was loaded then we store off the model path for the future
if (m_pStaticModel)
{
m_ModelFilename = modelFile;
}
}
}
}
IStatObj* CPreviewModelView::GetStaticModel()
{
return m_pStaticModel;
}
void CPreviewModelView::FocusOnScreen()
{
CCamera* camera = Camera();
if (camera)
{
AABB accumulated(2);
if (m_pStaticModel)
{
AABB temp;
temp.min = m_pStaticModel->GetBoxMin();
temp.max = m_pStaticModel->GetBoxMax();
accumulated.Add(temp);
}
Vec3 fromDir(1.0f, 1.0f, -0.5f);
Vec3 target = accumulated.GetCenter();
float bbRadius = accumulated.GetRadius();
Vec3 dir = fromDir.GetNormalized();
Matrix34 tm = Matrix33::CreateRotationVDir(dir, 0);
tm.SetTranslation(target - dir * bbRadius);
CameraMoved(QuatT(tm), true);
}
}
float CPreviewModelView::GetSpeedScale() const
{
CRY_ASSERT(GetIEditor());
CRY_ASSERT(GetIEditor()->GetSystem());
CRY_ASSERT(GetIEditor()->GetSystem()->GetITimer());
//Taken from CRenderViewport to mirror controls from there ...
float speedScale = 60.0f * GetIEditor()->GetSystem()->GetITimer()->GetFrameTime();
if (speedScale > 20.0f)
{
speedScale = 20.0f;
}
return speedScale;
}
@@ -1,173 +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
//Editor
#if !defined(Q_MOC_RUN)
#include "IEditor.h"
#include "../EditorCommon/QViewport.h"
#include "../EditorCommon/QViewportConsumer.h"
#endif
struct IStatObj;
struct SRenderingPassInfo;
struct SRendParams;
class CParticleItem;
class CAxisHelper;
struct HitContext;
struct IGizmoMouseDragHandler;
struct SLodInfo;
namespace RotationDrawHelper
{
class Axis;
}
AZ_PUSH_DISABLE_DLL_EXPORT_BASECLASS_WARNING
class CPreviewModelView
: public QViewport
, public QViewportConsumer
, public IEditorNotifyListener
{
AZ_POP_DISABLE_DLL_EXPORT_BASECLASS_WARNING
public:
enum class PlayState
{
NONE,
PLAY,
PAUSE,
STEP,
RESET
};
enum class SplineMode
{
NONE,
LINE,
SINEWAVE,
COIL
};
//NOTE: these need to be limited to 32 as these are being used for bit wise operations.
enum class PreviewModelViewFlag
{
DRAW_WIREFRAME = 0,
SHOW_BOUNDINGBOX,
SHOW_GIZMO,
SHOW_GRID,
SHOW_GRID_AXIS,
SHOW_EMITTER_SHAPE,
SHOW_OVERDRAW,
SHOW_FIRST_CONTAINER,
LOOPING_PLAY,
//Spline
SPLINE_LOOPING,
SPLINE_PINGPONG,
PRECACHE_MATERIAL,
ENABLE_TIME_OF_DAY,
END_POSSIBLE_ITEMS = 32,
};
explicit CPreviewModelView(QWidget* parent);
virtual ~CPreviewModelView();
//Flags
bool IsFlagSet(PreviewModelViewFlag flag) const;
void ToggleFlag(PreviewModelViewFlag flag);
virtual void SetFlag(PreviewModelViewFlag flag);
virtual void UnSetFlag(PreviewModelViewFlag flag);
//Resets
void ResetPlaybackControls();
void ResetBackgroundColor();
void ResetGridColor();
virtual void ResetCamera();
virtual void ResetAll();
void SetGridColor(ColorF color);
void SetBackgroundColor(ColorF color);
void SetPlayState(PlayState state);
void SetTimeScale(float scale);
PlayState GetPlayState() const;
float GetTimeScale() const;
ColorF GetGridColor() const;
ColorF GetBackgroundColor() const;
void ImportModel();
void LoadModelFile(const QString& modelFile);
IStatObj* GetStaticModel();
typedef std::function<void()> PostUpdateCallback;
void SetPostUpdateCallback(PostUpdateCallback callback);
typedef std::function<void(Vec2i mousePos)> ContextMenuCallback;
void SetContextMenuCallback(ContextMenuCallback callback);
////////////////////////////////////////////////////////
//QViewportConsumer
virtual void OnViewportRender(const SRenderContext& rc) override;
virtual void OnViewportKey(const SKeyEvent& ev) override;
virtual void OnViewportMouse(const SMouseEvent& ev) override;
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
//IEditorNotifyListener
virtual void OnEditorNotifyEvent(EEditorNotifyEvent event) override;
////////////////////////////////////////////////////////
private:
//Update
void UpdateSettings();
protected:
private:
//Render
void RenderModels(SRendParams& rendParams, SRenderingPassInfo& passInfo);
//Misc
void ReleaseModel();
void SetDefaultFlags();
protected:
void FocusOnScreen();
private:
float GetSpeedScale() const;
private:
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
ColorF m_GridColor;
ColorF m_BackgroundColor;
QString m_ModelFilename;
IStatObj* m_pStaticModel;
protected:
PostUpdateCallback m_PostUpdateCallback;
ContextMenuCallback m_ContextMenuCallback;
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
protected:
PlayState m_PlayState;
float m_TimeScale;
private:
unsigned int m_Flags;
};
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3e5d226d043630028a1fe88af240b627a08966066b605294cc79ff8273588166
size 194
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f80544a0537398979dd423ffdc8e99c08e47dbe814cd4225646761cbe281eecc
size 206
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bee8a3d1d5571e5afe0bd02edf0fc58d8297f96494a7c074fd2a37ecda7ae4dc
size 208
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3d0fc234e3154c06abd4e3b8d3d7e52a75f80d527b1d05541f55221cba199d7
size 183
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ffb3586ef4309d8bfa93a581c38fe970e8b0411f170955921054522b0bf52bd3
size 182
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f258e9617a1d4c7be16fcab12533a4f0bfe4072151f2140ca41364ef1a3cea62
size 196
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:68c609d7bde1796f281690148c19694afddcc2cf4ea306116b546327cb50aad2
size 249
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:bd5106eebb6cf264fdac5f3568977fc8f944df4a4d4de6b0e9f35b3a001a3001
size 206
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2b08a8d94c64aed944901b76afcb921c3df2c122c9eac6d52140552c2eb4e5cc
size 227
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:623a937f09f1de3ebb889d7ac9e042f91bf67bef34695801b3603f4517166c8e
size 223
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:623a937f09f1de3ebb889d7ac9e042f91bf67bef34695801b3603f4517166c8e
size 223
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0ad56ab7be0a5a40b644045ac01c90fed6e70433a693e80c5b4b88d63801d75f
size 14604
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9cc845c4eb0ed6fb772064d73f1c679e3b28288411a02f0cafaf248b83b44ca2
size 221
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:966fd5ef5c1e0fe6e920511952d7aea98ad0f165f9ce0197f000f9f48ccd338b
size 14628
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:966fd5ef5c1e0fe6e920511952d7aea98ad0f165f9ce0197f000f9f48ccd338b
size 14628
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c4a8dc85c9928faacd184148aaf0f17ef7b68c185b04b0b5f16e942fb11c528e
size 209

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