diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py deleted file mode 100755 index 41ae0608a4..0000000000 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test.py +++ /dev/null @@ -1,75 +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. -""" - -# -# This is a pytest module to test the in-Editor Python API from ViewPane.h -# -import pytest -pytest.importorskip('ly_test_tools') - -import sys -import os -sys.path.append(os.path.dirname(__file__)) -from hydra_utils import launch_test_case - - -@pytest.mark.SUITE_sandbox -@pytest.mark.parametrize('launcher_platform', ['windows_editor']) -@pytest.mark.parametrize('project', ['AutomatedTesting']) -@pytest.mark.parametrize('level', ['auto_test']) -class TestLegacyCryMaterialsCommandsAutomation(object): - - def test_Legacy_CryMaterials(self, request, editor, level, launcher_platform): - - unexpected_lines=[] - expected_lines = [ - # "Material Settings/Shader updated correctly", # Disabled, SPEC-3590 - # "Material Settings/Surface Type updated correctly", # Disabled, SPEC-3590 - "Texture Maps/Diffuse/Tiling/IsTileU updated correctly", - "Texture Maps/Diffuse/Tiling/TileU updated correctly", - "Texture Maps/Diffuse/Rotator/Type updated correctly", - "Texture Maps/Diffuse/Rotator/Amplitude updated correctly", - "Texture Maps/Diffuse/Oscillator/AmplitudeU updated correctly", - "Opacity Settings/Opacity updated correctly", - "Opacity Settings/AlphaTest updated correctly", - "Opacity Settings/Additive updated correctly", - "Lighting Settings/Diffuse Color updated correctly", - "Lighting Settings/Specular Color updated correctly", - "Lighting Settings/Emissive Intensity updated correctly", - "Lighting Settings/Emissive Color updated correctly", - "Advanced/Allow layer activation updated correctly", - "Advanced/2 Sided updated correctly", - "Advanced/No Shadow updated correctly", - "Advanced/Use Scattering updated correctly", - "Advanced/Hide After Breaking updated correctly", - "Advanced/Fog Volume Shading Quality High updated correctly", - "Advanced/Blend Terrain Color updated correctly", - "Advanced/Voxel Coverage updated correctly", - "Advanced/Propagate Opacity Settings updated correctly", - "Advanced/Propagate Lighting Settings updated correctly", - "Advanced/Propagate Advanced Settings updated correctly", - "Advanced/Propagate Texture Maps updated correctly", - "Advanced/Propagate Shader Params updated correctly", - "Advanced/Propagate Shader Generation updated correctly", - "Advanced/Propagate Vertex Deformation updated correctly", - # "Shader Params/Blend Factor updated correctly", # Disabled, SPEC-3590 - # "Shader Params/Indirect bounce color updated correctly", # Disabled, SPEC-3590 - "Vertex Deformation/Type updated correctly", - "Vertex Deformation/Wave Length X updated correctly", - "Vertex Deformation/Wave X/Level updated correctly", - "Vertex Deformation/Wave X/Amplitude updated correctly", - "Vertex Deformation/Wave X/Phase updated correctly", - "Vertex Deformation/Wave X/Frequency updated correctly" - ] - - test_case_file = os.path.join(os.path.dirname(__file__), 'CryMaterialsCommands_test_case.py') - launch_test_case(editor, test_case_file, expected_lines, unexpected_lines) - diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py deleted file mode 100755 index 913b1ace24..0000000000 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CryMaterialsCommands_test_case.py +++ /dev/null @@ -1,116 +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. -""" - -# Tests the legacy Python API for CryMaterials while the Editor is running - -import azlmbr.bus as bus -import azlmbr.editor as editor -import azlmbr.legacy.material as material -import azlmbr.math as math - -materialName = 'materials/ter_layer_green' -print(f'Starting CryMaterial test case using material {materialName}') - - -def MaterialPropertyTest(property, value, doReset=True): - try: - # get old value and attempt to set new value - oldValue = material.get_property(materialName, property) - if oldValue == value: - print(f'>>> `{property}` already set to {oldValue}') - return - material.set_property(materialName, property, value) - - # test that the set new value worked - newValue = material.get_property(materialName, property) - if oldValue != newValue: - print(f"{property} updated correctly") - - # reset back to old value - if doReset: - material.set_property(materialName, property, oldValue) - except: - print(f'!!! hit an exception when setting `{property}` to {value}') - - -color = math.Color() -color.r = 255.0 -color.g = 128.0 -color.b = 64.0 -color.a = 0.0 - -# Material Settings -# MaterialPropertyTest("Material Settings/Shader", "Geometrybeam") # Disabled, SPEC-3590 -# MaterialPropertyTest("Material Settings/Surface Type", "grass") # Disabled, SPEC-3590 - -# Texture Maps -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileU", False) -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/IsTileV", False) -MaterialPropertyTest("Texture Maps/Diffuse/Tiling/TileU", 0.42) -MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Type", 'Oscillated Rotation') -MaterialPropertyTest("Texture Maps/Diffuse/Rotator/Amplitude", 42.0) -MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/TypeU", 'Fixed Moving') -MaterialPropertyTest("Texture Maps/Diffuse/Oscillator/AmplitudeU", 42.0) - -# Vertex Deformation -MaterialPropertyTest("Vertex Deformation/Type", 'Sin Wave') -MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0) -MaterialPropertyTest("Vertex Deformation/Type", 'Perlin 3D') -MaterialPropertyTest("Vertex Deformation/Noise Scale", math.Vector3(1.1, 2.2, 3.3)) - -# Opacity Settings -MaterialPropertyTest("Opacity Settings/Opacity", 42) -MaterialPropertyTest("Opacity Settings/AlphaTest", 2) -MaterialPropertyTest("Opacity Settings/Additive", True) - -# Lighting Settings -MaterialPropertyTest("Lighting Settings/Diffuse Color", color) -MaterialPropertyTest("Lighting Settings/Specular Color", color) -MaterialPropertyTest("Lighting Settings/Emissive Intensity", 42.0) -MaterialPropertyTest("Lighting Settings/Emissive Color", color) -MaterialPropertyTest("Lighting Settings/Specular Level", 2.0) - -# Advanced -MaterialPropertyTest("Advanced/Allow layer activation", False) -MaterialPropertyTest("Advanced/2 Sided", True) -MaterialPropertyTest("Advanced/No Shadow", True) -MaterialPropertyTest("Advanced/Use Scattering", True) -MaterialPropertyTest("Advanced/Hide After Breaking", True) -MaterialPropertyTest("Advanced/Fog Volume Shading Quality High", True) -MaterialPropertyTest("Advanced/Blend Terrain Color", True) -MaterialPropertyTest("Advanced/Voxel Coverage", 0.42) -# --- MaterialPropertyTest("Advanced/Link to Material", "materials/ter_layer_blue") # Works, but clears on UI refresh -MaterialPropertyTest("Advanced/Propagate Opacity Settings", True) -MaterialPropertyTest("Advanced/Propagate Lighting Settings", True) -MaterialPropertyTest("Advanced/Propagate Advanced Settings", True) -MaterialPropertyTest("Advanced/Propagate Texture Maps", True) -MaterialPropertyTest("Advanced/Propagate Shader Params", True) -MaterialPropertyTest("Advanced/Propagate Shader Generation", True) -MaterialPropertyTest("Advanced/Propagate Vertex Deformation", True) - -# Shader parameters vary with each Shader, just testing a couple of them... -# MaterialPropertyTest("Shader Params/Blend Factor", 7.0, False) # Disabled, SPEC-3590 -# MaterialPropertyTest("Shader Params/Indirect bounce color", color, False) # Disabled, SPEC-3590 - -### These values are reset to False when set. Left them here commented for reference. -# MaterialPropertyTest("Shader Generation Params/Dust & Turbulence", True) -# MaterialPropertyTest("Shader Generation Params/Receive Shadows", True) -# MaterialPropertyTest("Shader Generation Params/UV Vignetting", True) - -# Vertex Deformation -MaterialPropertyTest("Vertex Deformation/Type", "Sin Wave") -MaterialPropertyTest("Vertex Deformation/Wave Length X", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Level", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Amplitude", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Phase", 42.0) -MaterialPropertyTest("Vertex Deformation/Wave X/Frequency", 42.0) - -editor.EditorToolsApplicationRequestBus(bus.Broadcast, 'ExitNoPrompt') diff --git a/Code/CryEngine/CryCommon/CREVolumeObject.h b/Code/CryEngine/CryCommon/CREVolumeObject.h index d84c7b3e50..2137053a8e 100644 --- a/Code/CryEngine/CryCommon/CREVolumeObject.h +++ b/Code/CryEngine/CryCommon/CREVolumeObject.h @@ -55,7 +55,7 @@ public: Matrix34 m_matInv; Vec3 m_eyePosInWS; Vec3 m_eyePosInOS; - Plane m_volumeTraceStartPlane; + Plane_tpl m_volumeTraceStartPlane; AABB m_renderBoundsOS; bool m_viewerInsideVolume; bool m_nearPlaneIntersectsVolume; diff --git a/Code/CryEngine/CryCommon/CREWaterOcean.h b/Code/CryEngine/CryCommon/CREWaterOcean.h index 784588309f..e8ca310d41 100644 --- a/Code/CryEngine/CryCommon/CREWaterOcean.h +++ b/Code/CryEngine/CryCommon/CREWaterOcean.h @@ -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& pl); virtual void Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof); void ReleaseOcean(); diff --git a/Code/CryEngine/CryCommon/CREWaterVolume.h b/Code/CryEngine/CryCommon/CREWaterVolume.h index 3e7a0636e6..89102e3097 100644 --- a/Code/CryEngine/CryCommon/CREWaterVolume.h +++ b/Code/CryEngine/CryCommon/CREWaterVolume.h @@ -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& 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 m_fogPlane; float m_fogDensity; Vec3 m_fogColor; bool m_fogColorAffectedBySun; diff --git a/Code/CryEngine/CryCommon/Cry_Camera.h b/Code/CryEngine/CryCommon/Cry_Camera.h index a744d7335f..56a764d897 100644 --- a/Code/CryEngine/CryCommon/Cry_Camera.h +++ b/Code/CryEngine/CryCommon/Cry_Camera.h @@ -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* 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 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& 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::CreatePlane(m_crtn + GetPosition(), m_cltn + GetPosition(), m_crbn + GetPosition()); + m_fp[FR_PLANE_RIGHT ] = Plane_tpl::CreatePlane(m_crbf + GetPosition(), m_crtf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_LEFT ] = Plane_tpl::CreatePlane(m_cltf + GetPosition(), m_clbf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_TOP ] = Plane_tpl::CreatePlane(m_crtf + GetPosition(), m_cltf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_BOTTOM] = Plane_tpl::CreatePlane(m_clbf + GetPosition(), m_crbf + GetPosition(), GetPosition()); + m_fp[FR_PLANE_FAR ] = Plane_tpl::CreatePlane(m_crtf + GetPosition(), m_crbf + GetPosition(), m_cltf + GetPosition()); //clip-plane uint32 rh = m_Matrix.IsOrthonormalRH(); if (rh == 0) diff --git a/Code/CryEngine/CryCommon/Cry_GeoDistance.h b/Code/CryEngine/CryCommon/Cry_GeoDistance.h index 92c1f65d87..47794c7671 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoDistance.h +++ b/Code/CryEngine/CryCommon/Cry_GeoDistance.h @@ -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 //---------------------------------------------------------------------------------- diff --git a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h index c2f556c4b7..89f6d8ebaf 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h +++ b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h @@ -22,7 +22,7 @@ #include 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& 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& plane, Vec3& output, bool bSingleSidePlane = true) { float cosine = plane.n | line.direction; diff --git a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h index 3f2c7081d7..ab560b7518 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h +++ b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h @@ -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 plane = Plane_tpl::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 plane = Plane_tpl::CreatePlane((e0 % e1), v0); Vec3 vmin, vmax; if (plane.n.x > 0.0f) diff --git a/Code/CryEngine/CryCommon/I3DEngine.h b/Code/CryEngine/CryCommon/I3DEngine.h index 8d3801ecb4..883b0a6d3b 100644 --- a/Code/CryEngine/CryCommon/I3DEngine.h +++ b/Code/CryEngine/CryCommon/I3DEngine.h @@ -458,7 +458,7 @@ struct SClipVolumeBlendInfo { static const int BlendPlaneCount = 2; - Plane blendPlanes[BlendPlaneCount]; + Plane_tpl blendPlanes[BlendPlaneCount]; struct IClipVolume* blendVolumes[BlendPlaneCount]; }; diff --git a/Code/CryEngine/CryCommon/IEntityRenderState.h b/Code/CryEngine/CryCommon/IEntityRenderState.h index 912f4632ab..92ff354eff 100644 --- a/Code/CryEngine/CryCommon/IEntityRenderState.h +++ b/Code/CryEngine/CryCommon/IEntityRenderState.h @@ -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& 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& fogPlane, bool keepSerializationParams = false, int nSID = -1) = 0; virtual void CreateRiver(uint64 volumeID, const AZStd::vector& 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; diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index 1e8553ac57..7fcbdefebb 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -52,7 +52,6 @@ struct SShaderItem; class ITexture; struct IMaterial; struct SParam; -class CMaterial; struct SShaderSerializeContext; struct IAnimNode; struct SSkinningData; diff --git a/Code/CryEngine/CryCommon/RendElement.h b/Code/CryEngine/CryCommon/RendElement.h index c3dc1c080d..41bcf2bf67 100644 --- a/Code/CryEngine/CryCommon/RendElement.h +++ b/Code/CryEngine/CryCommon/RendElement.h @@ -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& 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& 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; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBundle/AssetBundleComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBundle/AssetBundleComponent.cpp index 61e144d338..95319d2e6b 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBundle/AssetBundleComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AssetBundle/AssetBundleComponent.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -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::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(assetBundleSettings.m_maxBundleSizeInMB * NumOfBytesInMB); AZ::u64 assetCatalogFileSizeBuffer = static_cast(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 dependentBundleNames; AZStd::vector 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())) { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp index e7037c8936..373787e7dd 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/AzToolsFrameworkModule.cpp @@ -53,7 +53,6 @@ #include #include #include -#include #include 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(), diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h b/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h deleted file mode 100644 index b0d625b6e4..0000000000 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserBus.h +++ /dev/null @@ -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 - -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; - } // namespace MaterialBrowser -} // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.cpp deleted file mode 100644 index f64d4af23d..0000000000 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.cpp +++ /dev/null @@ -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 - -#include -#include -#include -#include -#include -#include - -#include -AZ_PUSH_DISABLE_WARNING(4251, "-Wunknown-warning-option") // 4251: 'QBrush::d': class 'QScopedPointer' needs to have dll-interface to be used by clients of class 'QBrush' -#include -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(context); - if (serialize) - { - serialize->Class(); - } - } - - void MaterialBrowserComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("ThumbnailerService", 0x65422b97)); - } - } // namespace MaterialBrowser -} // namespace AzToolsFramework - diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h deleted file mode 100644 index 93a48cf22c..0000000000 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialBrowserComponent.h +++ /dev/null @@ -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 -#include - -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 diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.cpp deleted file mode 100644 index e04df8937c..0000000000 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.cpp +++ /dev/null @@ -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 - -#include - -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(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() {} - - 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(key.data()); - } - - } // namespace MaterialBrowser -} // namespace AzToolsFramework - -#include "MaterialBrowser/moc_MaterialThumbnail.cpp" diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.h b/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.h deleted file mode 100644 index 60a2bb11e5..0000000000 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/MaterialBrowser/MaterialThumbnail.h +++ /dev/null @@ -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 -#include -#include -#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(val1.data()); - auto productThumbnailKey2 = azrtti_cast(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 - { - 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 - - diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 4cf121c517..a7fcf2e711 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -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 diff --git a/Code/Sandbox/Editor/Controls/PreviewModelCtrl.cpp b/Code/Sandbox/Editor/Controls/PreviewModelCtrl.cpp index 5746e9db2f..9b07f59e6a 100644 --- a/Code/Sandbox/Editor/Controls/PreviewModelCtrl.cpp +++ b/Code/Sandbox/Editor/Controls/PreviewModelCtrl.cpp @@ -365,10 +365,6 @@ bool CPreviewModelCtrl::Render() } _smart_ptr 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) diff --git a/Code/Sandbox/Editor/Controls/PreviewModelCtrl.h b/Code/Sandbox/Editor/Controls/PreviewModelCtrl.h index 73839612af..6388be9fd5 100644 --- a/Code/Sandbox/Editor/Controls/PreviewModelCtrl.h +++ b/Code/Sandbox/Editor/Controls/PreviewModelCtrl.h @@ -22,8 +22,6 @@ #include -#include - #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 m_pCurrentMaterial; CameraChangeCallback m_cameraChangeCallback; void* m_pCameraChangeUserData; diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyCtrl.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyCtrl.cpp index c21aff046e..f0367ffdc1 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyCtrl.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyCtrl.cpp @@ -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()); diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp index 3d17e77bb0..75344b2172 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.cpp @@ -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() { diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.h b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.h index d5ec0045c4..cdbb18ae12 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.h +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyGenericCtrl.h @@ -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; -using MaterialPropertyHandler = GenericPopupWidgetHandler; using ReverbPresetPropertyHandler = GenericPopupWidgetHandler; using MissionObjPropertyHandler = GenericPopupWidgetHandler; using SequencePropertyHandler = GenericPopupWidgetHandler; diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp index a66a73eaa4..e698b86341 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/PropertyResourceCtrl.cpp @@ -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) { diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp index 92610021b9..a188ee117b 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp @@ -361,16 +361,6 @@ void ReflectedPropertyControl::CreateItems(XmlNodeRef node, CVarBlockPtr& outBlo textureVar->Set(textureName); } } - else if (!azstricmp(type, "material")) - { - CSmartVariable 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 colorVar; diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.cpp index 055fc26a15..13584d9b82 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedPropertyItem.cpp @@ -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) { diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVar.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVar.cpp index a805c07a2f..12165d2be8 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVar.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVar.cpp @@ -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: diff --git a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp index 84a7f8c26f..b2fc07073f 100644 --- a/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp +++ b/Code/Sandbox/Editor/Controls/ReflectedPropertyControl/ReflectedVarWrapper.cpp @@ -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(); } diff --git a/Code/Sandbox/Editor/CryEdit.cpp b/Code/Sandbox/Editor/CryEdit.cpp index e118104687..abffd1f995 100644 --- a/Code/Sandbox/Editor/CryEdit.cpp +++ b/Code/Sandbox/Editor/CryEdit.cpp @@ -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 - // AWSNativeSDK #include #include @@ -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() { diff --git a/Code/Sandbox/Editor/CryEdit.h b/Code/Sandbox/Editor/CryEdit.h index 8c0c4bd59b..bce7f0c90d 100644 --- a/Code/Sandbox/Editor/CryEdit.h +++ b/Code/Sandbox/Editor/CryEdit.h @@ -417,9 +417,6 @@ private: void OnChangemovespeedIncrease(); void OnChangemovespeedDecrease(); void OnChangemovespeedChangestep(); - void OnMaterialAssigncurrent(); - void OnMaterialResettodefault(); - void OnMaterialGetmaterial(); void OnFileSavelevelresources(); void OnClearRegistryData(); void OnValidatelevel(); diff --git a/Code/Sandbox/Editor/CryEditDoc.cpp b/Code/Sandbox/Editor/CryEditDoc.cpp index 41c49ab026..c144d93c46 100644 --- a/Code/Sandbox/Editor/CryEditDoc.cpp +++ b/Code/Sandbox/Editor/CryEditDoc.cpp @@ -51,7 +51,6 @@ #include "CryEdit.h" #include "ActionManager.h" #include "Include/IObjectManager.h" -#include "Material/MaterialManager.h" #include "ErrorReportDialog.h" #include "SurfaceTypeValidator.h" #include "ShaderCache.h" @@ -357,8 +356,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])); @@ -513,14 +510,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 ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Sandbox/Editor/DisplaySettings.cpp b/Code/Sandbox/Editor/DisplaySettings.cpp index bd4372ae70..75e5c54ae9 100644 --- a/Code/Sandbox/Editor/DisplaySettings.cpp +++ b/Code/Sandbox/Editor/DisplaySettings.cpp @@ -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); - } } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Sandbox/Editor/EditorToolsApplication.cpp b/Code/Sandbox/Editor/EditorToolsApplication.cpp index 97caaf612a..2e3d70795a 100644 --- a/Code/Sandbox/Editor/EditorToolsApplication.cpp +++ b/Code/Sandbox/Editor/EditorToolsApplication.cpp @@ -21,14 +21,12 @@ #include #include #include -#include // 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()); components.emplace_back(azrtti_typeid()); - components.emplace_back(azrtti_typeid()); // Add new Bus-based Python Bindings components.emplace_back(azrtti_typeid()); diff --git a/Code/Sandbox/Editor/ErrorReport.h b/Code/Sandbox/Editor/ErrorReport.h index f78410be62..b13f8ae120 100644 --- a/Code/Sandbox/Editor/ErrorReport.h +++ b/Code/Sandbox/Editor/ErrorReport.h @@ -19,7 +19,6 @@ #pragma once // forward declarations. -class CMaterial; class CParticleItem; #include "BaseLibraryItem.h" diff --git a/Code/Sandbox/Editor/Export/ExportManager.cpp b/Code/Sandbox/Editor/Export/ExportManager.cpp index b41872595a..638977b191 100644 --- a/Code/Sandbox/Editor/Export/ExportManager.cpp +++ b/Code/Sandbox/Editor/Export/ExportManager.cpp @@ -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 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); } } diff --git a/Code/Sandbox/Editor/Export/ExportManager.h b/Code/Sandbox/Editor/Export/ExportManager.h index 8904ef08ed..a27e54b085 100644 --- a/Code/Sandbox/Editor/Export/ExportManager.h +++ b/Code/Sandbox/Editor/Export/ExportManager.h @@ -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 m_faces; diff --git a/Code/Sandbox/Editor/GameExporter.cpp b/Code/Sandbox/Editor/GameExporter.cpp index 8f0b6f6d0f..64e1fc6514 100644 --- a/Code/Sandbox/Editor/GameExporter.cpp +++ b/Code/Sandbox/Editor/GameExporter.cpp @@ -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) { diff --git a/Code/Sandbox/Editor/GameExporter.h b/Code/Sandbox/Editor/GameExporter.h index 52731a7000..a428046f0a 100644 --- a/Code/Sandbox/Editor/GameExporter.h +++ b/Code/Sandbox/Editor/GameExporter.h @@ -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); diff --git a/Code/Sandbox/Editor/GameResourcesExporter.cpp b/Code/Sandbox/Editor/GameResourcesExporter.cpp index 564396d090..8a6c547dca 100644 --- a/Code/Sandbox/Editor/GameResourcesExporter.cpp +++ b/Code/Sandbox/Editor/GameResourcesExporter.cpp @@ -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); -} - diff --git a/Code/Sandbox/Editor/GameResourcesExporter.h b/Code/Sandbox/Editor/GameResourcesExporter.h index b408cbb42f..8236458cb3 100644 --- a/Code/Sandbox/Editor/GameResourcesExporter.h +++ b/Code/Sandbox/Editor/GameResourcesExporter.h @@ -44,7 +44,6 @@ private: void GetFilesFromObjects(); void GetFilesFromVarBlock(CVarBlock* pVB); void GetFilesFromVariable(IVariable* pVar); - void GetFilesFromMaterials(); }; #endif // CRYINCLUDE_EDITOR_GAMERESOURCESEXPORTER_H diff --git a/Code/Sandbox/Editor/IEditor.h b/Code/Sandbox/Editor/IEditor.h index 838f48573d..c03b99e128 100644 --- a/Code/Sandbox/Editor/IEditor.h +++ b/Code/Sandbox/Editor/IEditor.h @@ -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. diff --git a/Code/Sandbox/Editor/IEditorImpl.cpp b/Code/Sandbox/Editor/IEditorImpl.cpp index 060bf41189..61d24db90c 100644 --- a/Code/Sandbox/Editor/IEditorImpl.cpp +++ b/Code/Sandbox/Editor/IEditorImpl.cpp @@ -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() diff --git a/Code/Sandbox/Editor/IEditorImpl.h b/Code/Sandbox/Editor/IEditorImpl.h index 3c440dd5fc..d17a94807f 100644 --- a/Code/Sandbox/Editor/IEditorImpl.h +++ b/Code/Sandbox/Editor/IEditorImpl.h @@ -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; diff --git a/Code/Sandbox/Editor/Include/IErrorReport.h b/Code/Sandbox/Editor/Include/IErrorReport.h index 8afe269324..f25a1163a3 100644 --- a/Code/Sandbox/Editor/Include/IErrorReport.h +++ b/Code/Sandbox/Editor/Include/IErrorReport.h @@ -21,7 +21,6 @@ #include // forward declarations. -class CMaterial; class CParticleItem; class CBaseObject; class CBaseLibraryItem; diff --git a/Code/Sandbox/Editor/LevelInfo.cpp b/Code/Sandbox/Editor/LevelInfo.cpp index 4b8a6d5cac..81441a3797 100644 --- a/Code/Sandbox/Editor/LevelInfo.cpp +++ b/Code/Sandbox/Editor/LevelInfo.cpp @@ -20,7 +20,6 @@ // Editor #include "Util/fastlib.h" -#include "Material/MaterialManager.h" // for CMaterialManager #include @@ -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(); -} diff --git a/Code/Sandbox/Editor/LevelInfo.h b/Code/Sandbox/Editor/LevelInfo.h index 0611ad652e..515a21886e 100644 --- a/Code/Sandbox/Editor/LevelInfo.h +++ b/Code/Sandbox/Editor/LevelInfo.h @@ -27,7 +27,6 @@ public: private: void ValidateObjects(); - void ValidateMaterials(); IErrorReport* m_pReport; }; diff --git a/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h b/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h index 45810da2cf..6659e41122 100644 --- a/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h +++ b/Code/Sandbox/Editor/Lib/Tests/IEditorMock.h @@ -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* ()); diff --git a/Code/Sandbox/Editor/Lib/Tests/test_MaterialPythonFuncs.cpp b/Code/Sandbox/Editor/Lib/Tests/test_MaterialPythonFuncs.cpp deleted file mode 100644 index c27608b695..0000000000 --- a/Code/Sandbox/Editor/Lib/Tests/test_MaterialPythonFuncs.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -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()); - } -} diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index 96f4da7312..44d65af8cd 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -94,13 +94,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 diff --git a/Code/Sandbox/Editor/MatEditPreviewDlg.cpp b/Code/Sandbox/Editor/MatEditPreviewDlg.cpp deleted file mode 100644 index 4bac9b5e76..0000000000 --- a/Code/Sandbox/Editor/MatEditPreviewDlg.cpp +++ /dev/null @@ -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 -#include -#include - -// 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 diff --git a/Code/Sandbox/Editor/MatEditPreviewDlg.h b/Code/Sandbox/Editor/MatEditPreviewDlg.h deleted file mode 100644 index 870d1b901e..0000000000 --- a/Code/Sandbox/Editor/MatEditPreviewDlg.h +++ /dev/null @@ -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 -#include - -#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 m_previewCtrl; - QScopedPointer m_menubar; -}; - -#endif // CRYINCLUDE_EDITOR_MATEDITPREVIEWDLG_H diff --git a/Code/Sandbox/Editor/Material/Material.cpp b/Code/Sandbox/Editor/Material/Material.cpp deleted file mode 100644 index 3d642a53dd..0000000000 --- a/Code/Sandbox/Editor/Material/Material.cpp +++ /dev/null @@ -1,1982 +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 "Material.h" - -// Editor -#include "MaterialHelpers.h" -#include "MaterialManager.h" -#include "UsedResources.h" -#include "ErrorReport.h" -#include "Include/ISourceControl.h" -#include "Undo/IUndoObject.h" - - -static SInputShaderResources defaultShaderResource; - -////////////////////////////////////////////////////////////////////////// -CMaterial::CMaterial(const QString& name, int nFlags) - : m_highlightFlags(0) - , m_dccMaterialHash(0) -{ - m_scFileAttributes = SCC_FILE_ATTRIBUTE_NORMAL; - - m_pParent = 0; - - m_shaderResources = defaultShaderResource; - m_shaderResources.m_LMaterial.m_Opacity = 1; - m_shaderResources.m_LMaterial.m_Diffuse.Set(1.0f, 1.0f, 1.0f, 1.0f); - m_shaderResources.m_LMaterial.m_Specular.Set(0.045f, 0.045f, 0.045f, 1.0f); // default 59 spec + div by Gamma exponent -> lin - m_shaderResources.m_LMaterial.m_Smoothness = 10.0f; - - m_mtlFlags = nFlags; - ZeroStruct(m_shaderItem); - - // Default shader. - m_shaderName = "Illum"; - m_nShaderGenMask = 0; - - m_name = name; - m_bRegetPublicParams = true; - m_bKeepPublicParamsValues = false; - m_bIgnoreNotifyChange = false; - m_bDummyMaterial = false; - - m_pMatInfo = NULL; - m_propagationFlags = 0; - - m_allowLayerActivation = true; -} - -CMaterial::CMaterial(const CMaterial& rhs) - : m_scFileAttributes{rhs.m_scFileAttributes} - , m_pParent{nullptr} - , m_shaderResources{rhs.m_shaderResources} - , m_mtlFlags{rhs.m_mtlFlags} - , m_shaderName{rhs.m_shaderName} - , m_nShaderGenMask{rhs.m_nShaderGenMask} - , m_bRegetPublicParams{rhs.m_bRegetPublicParams} - , m_bKeepPublicParamsValues{rhs.m_bKeepPublicParamsValues} - , m_bDummyMaterial{rhs.m_bDummyMaterial} - , m_pMatInfo{nullptr} - , m_propagationFlags{rhs.m_propagationFlags} - , m_allowLayerActivation{rhs.m_allowLayerActivation} - , m_dccMaterialHash(rhs.m_dccMaterialHash) -{ - ZeroStruct(m_shaderItem); - m_name = rhs.m_name; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial::~CMaterial() -{ - if (IsModified()) - { - Save(false); - } - - // Release used shader. - SAFE_RELEASE(m_shaderItem.m_pShader); - SAFE_RELEASE(m_shaderItem.m_pShaderResources); - - if (m_pMatInfo) - { - m_pMatInfo->SetUserData(0); - m_pMatInfo = 0; - } - - if (!m_subMaterials.empty()) - { - for (int i = 0; i < m_subMaterials.size(); i++) - { - if (m_subMaterials[i]) - { - m_subMaterials[i]->m_pParent = NULL; - } - } - - m_subMaterials.clear(); - } - - if (!IsPureChild() && !(GetFlags() & MTL_FLAG_UIMATERIAL)) - { - // Unregister this material from manager. - // Don't use here local variable m_pManager. Manager can be destroyed. - if (GetIEditor()->GetMaterialManager()) - { - GetIEditor()->GetMaterialManager()->DeleteItem(this); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetName(const QString& name) -{ - if (name != m_name) - { - QString oldName = GetFullName(); - m_name = name; - - if (!IsPureChild()) - { - if (GetIEditor()->GetMaterialManager()) - { - GetIEditor()->GetMaterialManager()->OnRenameItem(this, oldName); - } - - if (m_pMatInfo) - { - GetIEditor()->Get3DEngine()->GetMaterialManager()->RenameMaterial(m_pMatInfo, GetName().toUtf8().data()); - } - } - else - { - if (m_pMatInfo) - { - m_pMatInfo->SetName(m_name.toUtf8().data()); - } - } - - NotifyChanged(); - } - - if (m_shaderItem.m_pShaderResources) - { - // Only for correct warning message purposes. - m_shaderItem.m_pShaderResources->SetMaterialName(m_name.toUtf8().data()); - } -} - - -////////////////////////////////////////////////////////////////////////// -QString CMaterial::GetFilename() const -{ - return GetIEditor()->GetMaterialManager()->MaterialToFilename(IsPureChild() && m_pParent ? m_pParent->m_name : m_name); -} - -////////////////////////////////////////////////////////////////////////// -int CMaterial::GetTextureFilenames(QStringList& outFilenames) const -{ - for (auto& iter : m_shaderResources.m_TexturesResourcesMap ) - { - const SEfResTexture* pTexture = (const SEfResTexture*) &(iter.second); - QString name = QtUtil::ToQString(pTexture->m_Name); - if (name.isEmpty()) - { - AZ_Warning("Shaders System", false, "Error: CMaterial::GetTextureFilenames - texture slot name does not exist for slot %d", iter.first ); - continue; - } - - // Collect image filenames - if (IResourceCompilerHelper::IsSourceImageFormatSupported(name.toUtf8().data())) - { - stl::push_back_unique(outFilenames, Path::GamePathToFullPath(name)); - } - - // collect source files used in DCC tools - QString dccFilename; - if (CFileUtil::CalculateDccFilename(name, dccFilename)) - { - stl::push_back_unique(outFilenames, Path::GamePathToFullPath(dccFilename)); - } - } - - if (IsMultiSubMaterial()) - { - for (int i = 0; i < GetSubMaterialCount(); ++i) - { - CMaterial* pSubMtl = GetSubMaterial(i); - if (pSubMtl) - { - pSubMtl->GetTextureFilenames(outFilenames); - } - } - } - - return outFilenames.size(); -} - -////////////////////////////////////////////////////////////////////////// -int CMaterial::GetAnyTextureFilenames(QStringList& outFilenames) const -{ - for ( auto& iter : m_shaderResources.m_TexturesResourcesMap ) - { - QString name = QtUtil::ToQString( iter.second.m_Name); - if (name.isEmpty()) - { - continue; - } - - // Collect any filenames - stl::push_back_unique(outFilenames, Path::GamePathToFullPath(name)); - } - - if (IsMultiSubMaterial()) - { - for (int i = 0; i < GetSubMaterialCount(); ++i) - { - CMaterial* pSubMtl = GetSubMaterial(i); - if (pSubMtl) - { - pSubMtl->GetAnyTextureFilenames(outFilenames); - } - } - } - - return outFilenames.size(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::UpdateFileAttributes(bool useSourceControl) -{ - QString filename = GetFilename(); - if (filename.isEmpty()) - { - return; - } - - m_scFileAttributes = CFileUtil::GetAttributes(filename.toUtf8().data(), useSourceControl); -} - -////////////////////////////////////////////////////////////////////////// -uint32 CMaterial::GetFileAttributes() -{ - if (IsDummy()) - { - return m_scFileAttributes; - } - - if (IsPureChild() && m_pParent) - { - return m_pParent->GetFileAttributes(); - } - - UpdateFileAttributes(); - return m_scFileAttributes; -}; - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetShaderName(const QString& shaderName) -{ - if (m_shaderName != shaderName) - { - m_bRegetPublicParams = true; - m_bKeepPublicParamsValues = false; - - RecordUndo("Change Shader"); - } - - m_shaderName = shaderName; - if (QString::compare(m_shaderName, "nodraw", Qt::CaseInsensitive) == 0) - { - m_mtlFlags |= MTL_FLAG_NODRAW; - } - else - { - m_mtlFlags &= ~MTL_FLAG_NODRAW; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::CheckSpecialConditions() -{ - if (QString::compare(m_shaderName, "nodraw", Qt::CaseInsensitive) == 0) - { - m_mtlFlags |= MTL_FLAG_NODRAW; - } - else - { - m_mtlFlags &= ~MTL_FLAG_NODRAW; - } - - // If environment texture name have auto/nearest cubemap in it, force material to use auto cube-map for it. - SEfResTexture* pTextureRes = m_shaderResources.GetTextureResource(EFTT_ENV); - if (!pTextureRes) - return; - - if (!pTextureRes->m_Name.empty()) - { - const char* sAtPos; - sAtPos = strstr(pTextureRes->m_Name.c_str(), "auto_2d"); - if (sAtPos) - { - pTextureRes->m_Sampler.m_eTexType = eTT_Auto2D; // Force Auto-2D - } - sAtPos = strstr(pTextureRes->m_Name.c_str(), "nearest_cubemap"); - if (sAtPos) - { - pTextureRes->m_Sampler.m_eTexType = eTT_NearestCube; // Force Nearest Cubemap - } - } - - // Force auto 2D map if user sets texture type - if (pTextureRes->m_Sampler.m_eTexType == eTT_Auto2D) - { - pTextureRes->m_Name = "auto_2d"; - } - - // Force nearest cube map if user sets texture type - if (pTextureRes->m_Sampler.m_eTexType == eTT_NearestCube) - { - pTextureRes->m_Name = "nearest_cubemap"; - m_mtlFlags |= MTL_FLAG_REQUIRE_NEAREST_CUBEMAP; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterial::LoadShader() -{ - if (m_bDummyMaterial) - { - return true; - } - - CheckSpecialConditions(); - - GetIEditor()->GetErrorReport()->SetCurrentValidatorItem(this); - - m_shaderResources.m_ResFlags = m_mtlFlags; - - QString sShader = m_shaderName; - if (sShader.isEmpty()) - { - sShader = ""; - } - - QByteArray n = m_name.toUtf8(); - m_shaderResources.m_szMaterialName = n.data(); - SShaderItem newShaderItem = GetIEditor()->GetRenderer()->EF_LoadShaderItem(sShader.toUtf8().data(), false, 0, &m_shaderResources, m_nShaderGenMask); - - // Shader not found - if (newShaderItem.m_pShader && (newShaderItem.m_pShader->GetFlags() & EF_NOTFOUND) != 0) - { - CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "Failed to load shader \"%s\" in material \"%s\"", newShaderItem.m_pShader->GetName(), m_name.toUtf8().constData()); - } - - // Release previously used shader (Must be After new shader is loaded, for speed). - SAFE_RELEASE(m_shaderItem.m_pShader); - SAFE_RELEASE(m_shaderItem.m_pShaderResources); - - m_shaderItem = newShaderItem; - if (!m_shaderItem.m_pShader) - { - CErrorRecord err; - - err.error = QObject::tr("Failed to Load Shader %1").arg(m_shaderName); - err.pItem = this; - - GetIEditor()->GetErrorReport()->ReportError(err); - GetIEditor()->GetErrorReport()->SetCurrentValidatorItem(NULL); - return false; - } - - IShader* pShader = m_shaderItem.m_pShader; - m_nShaderGenMask = pShader->GetGenerationMask(); - if (pShader->GetFlags() & EF_NOPREVIEW) - { - m_mtlFlags |= MTL_FLAG_NOPREVIEW; - } - else - { - m_mtlFlags &= ~MTL_FLAG_NOPREVIEW; - } - - ////////////////////////////////////////////////////////////////////////// - // Reget shader parms. - ////////////////////////////////////////////////////////////////////////// - if (m_bRegetPublicParams) - { - if (m_bKeepPublicParamsValues) - { - m_bKeepPublicParamsValues = false; - m_publicVarsCache = XmlHelpers::CreateXmlNode("PublicParams"); - - MaterialHelpers::SetXmlFromShaderParams(m_shaderResources, m_publicVarsCache); - } - - m_shaderResources.m_ShaderParams = pShader->GetPublicParams(); - m_bRegetPublicParams = false; - } - - ////////////////////////////////////////////////////////////////////////// - // If we have XML node with public parameters loaded, apply it on shader parms. - ////////////////////////////////////////////////////////////////////////// - if (m_publicVarsCache) - { - MaterialHelpers::SetShaderParamsFromXml(m_shaderResources, m_publicVarsCache); - GetIEditor()->GetMaterialManager()->OnUpdateProperties(this, false); - m_publicVarsCache = 0; - } - - ////////////////////////////////////////////////////////////////////////// - // Set shader parms. - if (m_shaderItem.m_pShaderResources) - { - m_shaderItem.m_pShaderResources->SetShaderParams(&m_shaderResources, m_shaderItem.m_pShader); - } - ////////////////////////////////////////////////////////////////////////// - - gEnv->pRenderer->UpdateShaderItem(&m_shaderItem, nullptr); - - ////////////////////////////////////////////////////////////////////////// - // Set Shader Params for material layers - ////////////////////////////////////////////////////////////////////////// - if (m_pMatInfo) - { - UpdateMatInfo(); - } - - GetIEditor()->GetMaterialManager()->OnLoadShader(this); - GetIEditor()->GetErrorReport()->SetCurrentValidatorItem(NULL); - - return true; -} - -bool CMaterial::LoadMaterialLayers() -{ - if (!m_pMatInfo) - { - return false; - } - - if (m_shaderItem.m_pShader && m_shaderItem.m_pShaderResources) - { - // mask generation for base material shader - uint32 nMaskGenBase = m_shaderItem.m_pShader->GetGenerationMask(); - SShaderGen* pShaderGenBase = m_shaderItem.m_pShader->GetGenerationParams(); - - for (uint32 l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - SMaterialLayerResources* pCurrLayer = &m_pMtlLayerResources[l]; - pCurrLayer->m_nFlags |= MTL_FLAG_NODRAW; - if (!pCurrLayer->m_shaderName.isEmpty()) - { - if (QString::compare(pCurrLayer->m_shaderName, "nodraw", Qt::CaseInsensitive) == 0) - { - // no shader = skip layer - pCurrLayer->m_shaderName.clear(); - continue; - } - - IShader* pNewShader = GetIEditor()->GetRenderer()->EF_LoadShader(pCurrLayer->m_shaderName.toUtf8().data(), 0); - - // Check if shader loaded - if (!pNewShader || (pNewShader->GetFlags() & EF_NOTFOUND) != 0) - { - CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "Failed to load material layer shader \"%s\" in material \"%s\"", pCurrLayer->m_shaderName.toUtf8().constData(), m_pMatInfo->GetName()); - if (!pNewShader) - { - continue; - } - } - - if (!pCurrLayer->m_pMatLayer) - { - pCurrLayer->m_pMatLayer = m_pMatInfo->CreateLayer(); - } - - // mask generation for base material shader - uint64 nMaskGenLayer = 0; - SShaderGen* pShaderGenLayer = pNewShader->GetGenerationParams(); - if (pShaderGenBase && pShaderGenLayer) - { - for (int nLayerBit(0); nLayerBit < pShaderGenLayer->m_BitMask.size(); ++nLayerBit) - { - SShaderGenBit* pLayerBit = pShaderGenLayer->m_BitMask[nLayerBit]; - - for (int nBaseBit(0); nBaseBit < pShaderGenBase->m_BitMask.size(); ++nBaseBit) - { - SShaderGenBit* pBaseBit = pShaderGenBase->m_BitMask[nBaseBit]; - - // Need to check if flag name is common to both shaders (since flags values can be different), if so activate it on this layer - if (nMaskGenBase & pBaseBit->m_Mask) - { - if (!pLayerBit->m_ParamName.empty() && !pBaseBit->m_ParamName.empty()) - { - if (pLayerBit->m_ParamName == pBaseBit->m_ParamName) - { - nMaskGenLayer |= pLayerBit->m_Mask; - break; - } - } - } - } - } - } - - // Reload with proper flags - SShaderItem newShaderItem = GetIEditor()->GetRenderer()->EF_LoadShaderItem(pCurrLayer->m_shaderName.toUtf8().data(), false, 0, &pCurrLayer->m_shaderResources, nMaskGenLayer); - if (!newShaderItem.m_pShader || (newShaderItem.m_pShader->GetFlags() & EF_NOTFOUND) != 0) - { - CryWarning(VALIDATOR_MODULE_EDITOR, VALIDATOR_WARNING, "Failed to load material layer shader \"%s\" in material \"%s\"", pCurrLayer->m_shaderName.toUtf8().data(), m_pMatInfo->GetName()); - if (!newShaderItem.m_pShader) - { - continue; - } - } - - SShaderItem& pCurrShaderItem = pCurrLayer->m_pMatLayer->GetShaderItem(); - - if (newShaderItem.m_pShader) - { - newShaderItem.m_pShader->AddRef(); - } - - // Release previously used shader (Must be After new shader is loaded, for speed). - SAFE_RELEASE(pCurrShaderItem.m_pShader); - SAFE_RELEASE(pCurrShaderItem.m_pShaderResources); - SAFE_RELEASE(newShaderItem.m_pShaderResources); - - pCurrShaderItem.m_pShader = newShaderItem.m_pShader; - // Copy resources from base material - pCurrShaderItem.m_pShaderResources = m_shaderItem.m_pShaderResources->Clone(); - pCurrShaderItem.m_nTechnique = newShaderItem.m_nTechnique; - pCurrShaderItem.m_nPreprocessFlags = newShaderItem.m_nPreprocessFlags; - - // set default params - if (pCurrLayer->m_bRegetPublicParams) - { - pCurrLayer->m_shaderResources.m_ShaderParams = pCurrShaderItem.m_pShader->GetPublicParams(); - } - - pCurrLayer->m_bRegetPublicParams = false; - - if (pCurrLayer->m_publicVarsCache) - { - MaterialHelpers::SetShaderParamsFromXml(pCurrLayer->m_shaderResources, pCurrLayer->m_publicVarsCache); - pCurrLayer->m_publicVarsCache = 0; - } - - if (pCurrShaderItem.m_pShaderResources) - { - pCurrShaderItem.m_pShaderResources->SetShaderParams(&pCurrLayer->m_shaderResources, pCurrShaderItem.m_pShader); - } - - // Activate layer - pCurrLayer->m_nFlags &= ~MTL_FLAG_NODRAW; - } - } - - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// - -void CMaterial::UpdateMaterialLayers() -{ - if (m_pMatInfo && m_shaderItem.m_pShaderResources) - { - m_pMatInfo->SetLayerCount(MTL_LAYER_MAX_SLOTS); - - uint8 nMaterialLayerFlags = 0; - - for (int l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - SMaterialLayerResources* pCurrLayer = &m_pMtlLayerResources[l]; - if (pCurrLayer && !pCurrLayer->m_shaderName.isEmpty() && pCurrLayer->m_pMatLayer) - { - pCurrLayer->m_pMatLayer->SetFlags(pCurrLayer->m_nFlags); - m_pMatInfo->SetLayer(l, pCurrLayer->m_pMatLayer); - - if ((pCurrLayer->m_nFlags & MTL_LAYER_USAGE_NODRAW)) - { - if (!QString::compare(pCurrLayer->m_shaderName, "frozenlayerwip", Qt::CaseInsensitive)) - { - nMaterialLayerFlags |= MTL_LAYER_FROZEN; - } - } - } - } - - if (m_shaderItem.m_pShaderResources) - { - m_shaderItem.m_pShaderResources->SetMtlLayerNoDrawFlags(nMaterialLayerFlags); - } - } -} - -void CMaterial::UpdateMatInfo() -{ - if (m_pMatInfo) - { - // Mark material invalid. - m_pMatInfo->SetFlags(m_mtlFlags); - m_pMatInfo->SetShaderItem(m_shaderItem); - m_pMatInfo->SetShaderName(m_shaderName.toUtf8().constData()); - m_pMatInfo->SetSurfaceType(m_surfaceType.toUtf8().constData()); - - LoadMaterialLayers(); - UpdateMaterialLayers(); - - m_pMatInfo->SetMaterialLinkName(m_linkedMaterial.toUtf8().data()); - - if (IsMultiSubMaterial()) - { - m_pMatInfo->SetSubMtlCount(m_subMaterials.size()); - for (unsigned int i = 0; i < m_subMaterials.size(); i++) - { - if (m_subMaterials[i]) - { - m_pMatInfo->SetSubMtl(i, m_subMaterials[i]->GetMatInfo()); - } - else - { - m_pMatInfo->SetSubMtl(i, NULL); - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -CVarBlock* CMaterial::GetPublicVars(SInputShaderResources& pShaderResources) -{ - return MaterialHelpers::GetPublicVars(pShaderResources); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetShaderParamPublicScript() -{ - IShader* pShader = m_shaderItem.m_pShader; - - if (!pShader) - { - return; - } - - if (m_shaderResources.m_ShaderParams.size() == 0 || pShader->GetPublicParams().size() == 0) - { - return; - } - - // We want to inspect public shader param and paste the m_script into our shader resource param script - for (int i = 0; i < m_shaderResources.m_ShaderParams.size(); ++i) - { - SShaderParam ¤tShaderParam = m_shaderResources.m_ShaderParams.at(i); - for (int j = 0; j < pShader->GetPublicParams().size(); ++j) - { - const SShaderParam &publicShaderParam = pShader->GetPublicParams().at(j); - if ((currentShaderParam.m_Name == publicShaderParam.m_Name) && (currentShaderParam.m_Type == publicShaderParam.m_Type)) - { - currentShaderParam.m_Script = publicShaderParam.m_Script; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetPublicVars(CVarBlock* pPublicVars, CMaterial* pMtl) -{ - if (!pMtl->GetShaderResources().m_ShaderParams.empty()) - { - RecordUndo("Set Public Vars"); - } - - MaterialHelpers::SetPublicVars(pPublicVars, pMtl->GetShaderResources(), pMtl->GetShaderItem().m_pShaderResources, pMtl->GetShaderItem().m_pShader); - - GetIEditor()->GetMaterialManager()->OnUpdateProperties(this, false); -} - -////////////////////////////////////////////////////////////////////////// -CVarBlock* CMaterial::GetShaderGenParamsVars() -{ - return MaterialHelpers::GetShaderGenParamsVars(GetShaderItem().m_pShader, m_nShaderGenMask); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetShaderGenParamsVars(CVarBlock* pBlock) -{ - RecordUndo("Change Shader GenMask"); - - uint64 nGenMask = MaterialHelpers::SetShaderGenParamsVars(GetShaderItem().m_pShader, pBlock); - if (m_nShaderGenMask != nGenMask) - { - m_bRegetPublicParams = true; - m_bKeepPublicParamsValues = true; - m_nShaderGenMask = nGenMask; - } -} - -////////////////////////////////////////////////////////////////////////// -unsigned int CMaterial::GetTexmapUsageMask() const -{ - int mask = 0; - if (m_shaderItem.m_pShader) - { - IShader* pTempl = m_shaderItem.m_pShader; - if (pTempl) - { - mask = pTempl->GetUsedTextureTypes(); - } - } - return mask; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::Update() -{ - // Reload shader item with new resources and shader. - LoadShader(); - - // Mark library as modified. - SetModified(); - - GetIEditor()->SetModifiedFlag(); - - // When modifying pure child, mark his parent as modified. - if (IsPureChild() && m_pParent) - { - m_pParent->SetModified(); - } -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -void CMaterial::Serialize(SerializeContext& ctx) -{ - //CBaseLibraryItem::Serialize( ctx ); - - XmlNodeRef node = ctx.node; - if (ctx.bLoading) - { - m_bIgnoreNotifyChange = true; - m_bRegetPublicParams = true; - - SInputShaderResources& sr = m_shaderResources; - m_shaderResources = defaultShaderResource; - - // Loading - int flags = m_mtlFlags; - if (node->getAttr("MtlFlags", flags)) - { - m_mtlFlags &= ~(MTL_FLAGS_SAVE_MASK); - m_mtlFlags |= (flags & (MTL_FLAGS_SAVE_MASK)); - } - - uint32 dccMaterialHash = 0; - node->getAttr("DccMaterialHash", dccMaterialHash); - SetDccMaterialHash(dccMaterialHash); - - if (!IsMultiSubMaterial()) - { - node->getAttr("Shader", m_shaderName); - node->getAttr("GenMask", m_nShaderGenMask); - - if (!(m_mtlFlags & MTL_64BIT_SHADERGENMASK)) - { - uint32 nShaderGenMask = 0; - node->getAttr("GenMask", nShaderGenMask); - m_nShaderGenMask = nShaderGenMask; - } - else - { - node->getAttr("GenMask", m_nShaderGenMask); - } - - // Remap flags if needed - if (!(m_mtlFlags & MTL_64BIT_SHADERGENMASK)) - { - m_nShaderGenMask = GetIEditor()->GetRenderer()->EF_GetRemapedShaderMaskGen(m_shaderName.toUtf8().data(), m_nShaderGenMask); - m_mtlFlags |= MTL_64BIT_SHADERGENMASK; - } - - if (node->getAttr("StringGenMask", m_pszShaderGenMask)) - { - m_nShaderGenMask = GetIEditor()->GetRenderer()->EF_GetShaderGlobalMaskGenFromString(m_shaderName.toUtf8().data(), m_pszShaderGenMask.toUtf8().data(), m_nShaderGenMask); // get common mask gen - } - else - { - // version doens't has string gen mask yet ? Remap flags if needed - m_nShaderGenMask = GetIEditor()->GetRenderer()->EF_GetRemapedShaderMaskGen(m_shaderName.toUtf8().data(), m_nShaderGenMask, ((m_mtlFlags & MTL_64BIT_SHADERGENMASK) != 0)); - } - m_mtlFlags |= MTL_64BIT_SHADERGENMASK; - - node->getAttr("SurfaceType", m_surfaceType); - node->getAttr("LayerAct", m_allowLayerActivation); - - MaterialHelpers::SetLightingFromXml(sr, node); - - MaterialHelpers::SetTexturesFromXml(sr, node); - MaterialHelpers::MigrateXmlLegacyData(sr, node); - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have a link name and if any propagation settings were - // present - ////////////////////////////////////////////////////////////////////////// - XmlNodeRef pLinkName = node->findChild("MaterialLinkName"); - if (pLinkName) - { - m_linkedMaterial = pLinkName->getAttr("name"); - } - else - { - m_linkedMaterial = QString(); - } - - XmlNodeRef pPropagationFlags = node->findChild("MaterialPropagationFlags"); - if (pPropagationFlags) - { - pPropagationFlags->getAttr("flags", m_propagationFlags); - } - else - { - m_propagationFlags = 0; - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have vertex deform. - ////////////////////////////////////////////////////////////////////////// - MaterialHelpers::SetVertexDeformFromXml(m_shaderResources, node); - - // Serialize sub materials. - - const auto ResizeSubMaterials = [this](size_t count) - { - for (size_t i = count; i < m_subMaterials.size(); ++i) - { - if (auto& pSubMtl = m_subMaterials[i]) - { - pSubMtl->m_pParent = nullptr; - } - } - m_subMaterials.resize(count); - }; - - XmlNodeRef childsNode = node->findChild("SubMaterials"); - if (childsNode && !ctx.bIgnoreChilds) - { - QString name; - int nSubMtls = childsNode->getChildCount(); - ResizeSubMaterials(nSubMtls); - for (int i = 0; i < nSubMtls; i++) - { - auto& pSubMtl = m_subMaterials[i]; - XmlNodeRef mtlNode = childsNode->getChild(i); - if (mtlNode->isTag("Material")) - { - mtlNode->getAttr("Name", name); - if (pSubMtl && pSubMtl->IsPureChild()) - { - pSubMtl->SetName(name); - } - else - { - if (pSubMtl) - { - pSubMtl->m_pParent = nullptr; - } - - pSubMtl = new CMaterial(name, MTL_FLAG_PURE_CHILD); - pSubMtl->m_pParent = this; - } - - SerializeContext childCtx(ctx); - childCtx.node = mtlNode; - pSubMtl->Serialize(childCtx); - - pSubMtl->m_shaderResources.m_SortPrio = nSubMtls - i - 1; - } - else - { - if (pSubMtl) - { - pSubMtl->m_pParent = nullptr; - pSubMtl = nullptr; - } - - if (mtlNode->getAttr("Name", name)) - { - CMaterial* pMtl = GetIEditor()->GetMaterialManager()->LoadMaterial(name); - if (pMtl && !pMtl->IsMultiSubMaterial()) - { - pSubMtl = pMtl; - } - } - } - } - - m_subMaterials.erase(std::remove(m_subMaterials.begin(), m_subMaterials.end(), nullptr), m_subMaterials.end()); - } - else - { - ResizeSubMaterials(0); - } - - UpdateMatInfo(); - - ////////////////////////////////////////////////////////////////////////// - // Load public parameters. - ////////////////////////////////////////////////////////////////////////// - m_publicVarsCache = node->findChild("PublicParams"); - - ////////////////////////////////////////////////////////////////////////// - // Load material layers data - ////////////////////////////////////////////////////////////////////////// - XmlNodeRef mtlLayersNode = node->findChild("MaterialLayers"); - if (mtlLayersNode) - { - int nChildCount = min((int) MTL_LAYER_MAX_SLOTS, (int) mtlLayersNode->getChildCount()); - for (int l = 0; l < nChildCount; ++l) - { - XmlNodeRef layerNode = mtlLayersNode->getChild(l); - if (layerNode) - { - if (layerNode->getAttr("Name", m_pMtlLayerResources[l].m_shaderName)) - { - m_pMtlLayerResources[l].m_bRegetPublicParams = true; - - bool bNoDraw = false; - layerNode->getAttr("NoDraw", bNoDraw); - - m_pMtlLayerResources[l].m_publicVarsCache = layerNode->findChild("PublicParams"); - - if (bNoDraw) - { - m_pMtlLayerResources[l].m_nFlags |= MTL_LAYER_USAGE_NODRAW; - } - else - { - m_pMtlLayerResources[l].m_nFlags &= ~MTL_LAYER_USAGE_NODRAW; - } - - - bool bFadeOut = false; - layerNode->getAttr("FadeOut", bFadeOut); - if (bFadeOut) - { - m_pMtlLayerResources[l].m_nFlags |= MTL_LAYER_USAGE_FADEOUT; - } - else - { - m_pMtlLayerResources[l].m_nFlags &= ~MTL_LAYER_USAGE_FADEOUT; - } - } - } - } - } - - if (ctx.bUndo) - { - LoadShader(); - UpdateMatInfo(); - } - - m_bIgnoreNotifyChange = false; - - // If copy pasting or undo send update event. - if (ctx.bCopyPaste || ctx.bUndo) - { - NotifyChanged(); - } - - // NotifyChanged calls SetModified but since we just loaded it, its not actually changed. - SetModified(false); - } - else // If !ctx.bLoading - { - int extFlags = MTL_64BIT_SHADERGENMASK; - { - const QString& name = GetName(); - const size_t len = name.length(); - if (len > 4 && strstri(name.toUtf8().data() + (len - 4), "_con")) - { - extFlags |= MTL_FLAG_CONSOLE_MAT; - } - } - - // Saving. - node->setAttr("MtlFlags", m_mtlFlags | extFlags); - node->setAttr("DccMaterialHash", GetDccMaterialHash()); - - if (!IsMultiSubMaterial()) - { - // store shader gen bit mask string - m_pszShaderGenMask = GetIEditor()->GetRenderer()->EF_GetStringFromShaderGlobalMaskGen(m_shaderName.toUtf8().data(), m_nShaderGenMask).c_str(); - - node->setAttr("Shader", m_shaderName.toUtf8().data()); - node->setAttr("GenMask", m_nShaderGenMask); - node->setAttr("StringGenMask", m_pszShaderGenMask.toUtf8().data()); - node->setAttr("SurfaceType", m_surfaceType.toUtf8().data()); - - //if (!m_shaderName.IsEmpty() && (stricmp(m_shaderName,"nodraw") != 0)) - { - MaterialHelpers::SetXmlFromLighting(m_shaderResources, node); - MaterialHelpers::SetXmlFromTextures(m_shaderResources, node); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Save out the link name if present and the propagation flags - ////////////////////////////////////////////////////////////////////////// - if (!m_linkedMaterial.isEmpty()) - { - XmlNodeRef pLinkName = node->newChild("MaterialLinkName"); - pLinkName->setAttr("name", m_linkedMaterial.toUtf8().data()); - } - - if (m_propagationFlags) - { - XmlNodeRef pPropagationFlags = node->newChild("MaterialPropagationFlags"); - pPropagationFlags->setAttr("flags", m_propagationFlags); - } - - ////////////////////////////////////////////////////////////////////////// - // Check if we have vertex deform. - ////////////////////////////////////////////////////////////////////////// - MaterialHelpers::SetXmlFromVertexDeform(m_shaderResources, node); - - if (GetSubMaterialCount() > 0) - { - // Serialize sub materials. - - // Let's not serialize empty submaterials at the end of the list. - // Note that IDs of the remaining submaterials stay intact. - int count = GetSubMaterialCount(); - while (count > 0 && !GetSubMaterial(count - 1)) - { - --count; - } - - XmlNodeRef childsNode = node->newChild("SubMaterials"); - - for (int i = 0; i < count; ++i) - { - CMaterial* const pSubMtl = GetSubMaterial(i); - if (pSubMtl && pSubMtl->IsPureChild()) - { - XmlNodeRef mtlNode = childsNode->newChild("Material"); - mtlNode->setAttr("Name", pSubMtl->GetName().toUtf8().data()); - SerializeContext childCtx(ctx); - childCtx.node = mtlNode; - pSubMtl->Serialize(childCtx); - } - else - { - XmlNodeRef mtlNode = childsNode->newChild("MaterialRef"); - if (pSubMtl) - { - mtlNode->setAttr("Name", pSubMtl->GetName().toUtf8().data()); - } - } - } - } - - ////////////////////////////////////////////////////////////////////////// - // Save public parameters. - ////////////////////////////////////////////////////////////////////////// - if (m_publicVarsCache) - { - node->addChild(m_publicVarsCache); - } - else if (!m_shaderResources.m_ShaderParams.empty()) - { - XmlNodeRef publicsNode = node->newChild("PublicParams"); - MaterialHelpers::SetXmlFromShaderParams(m_shaderResources, publicsNode); - } - - ////////////////////////////////////////////////////////////////////////// - // Save material layers data - ////////////////////////////////////////////////////////////////////////// - - bool bMaterialLayers = false; - for (int l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - if (!m_pMtlLayerResources[l].m_shaderName.isEmpty()) - { - bMaterialLayers = true; - break; - } - } - - if (bMaterialLayers) - { - XmlNodeRef mtlLayersNode = node->newChild("MaterialLayers"); - for (int l(0); l < MTL_LAYER_MAX_SLOTS; ++l) - { - XmlNodeRef layerNode = mtlLayersNode->newChild("Layer"); - if (!m_pMtlLayerResources[l].m_shaderName.isEmpty()) - { - layerNode->setAttr("Name", m_pMtlLayerResources[l].m_shaderName.toUtf8().data()); - layerNode->setAttr("NoDraw", m_pMtlLayerResources[l].m_nFlags & MTL_LAYER_USAGE_NODRAW); - layerNode->setAttr("FadeOut", m_pMtlLayerResources[l].m_nFlags & MTL_LAYER_USAGE_FADEOUT); - - if (m_pMtlLayerResources[l].m_publicVarsCache) - { - layerNode->addChild(m_pMtlLayerResources[l].m_publicVarsCache); - } - else if (!m_pMtlLayerResources[l].m_shaderResources.m_ShaderParams.empty()) - { - XmlNodeRef publicsNode = layerNode->newChild("PublicParams"); - MaterialHelpers::SetXmlFromShaderParams(m_pMtlLayerResources[l].m_shaderResources, publicsNode); - } - } - } - } - - if (GetSubMaterialCount() == 0 || GetParent()) - { - node->setAttr("LayerAct", m_allowLayerActivation); - } - } -} - -/* -////////////////////////////////////////////////////////////////////////// -void CMaterial::SerializePublics( XmlNodeRef &node,bool bLoading ) -{ -if (bLoading) -{ -} -else -{ -if (m_shaderParams.empty()) -return; -XmlNodeRef publicsNode = node->newChild( "PublicParams" ); - -for (int i = 0; i < m_shaderParams.size(); i++) -{ -XmlNodeRef paramNode = node->newChild( "Param" ); -SShaderParam *pParam = &m_shaderParams[i]; -paramNode->setAttr( "Name",pParam->m_Name ); -switch (pParam->m_Type) -{ -case eType_BYTE: -paramNode->setAttr( "Value",(int)pParam->m_Value.m_Byte ); -paramNode->setAttr( "Type",(int)pParam->m_Value.m_Byte ); -break; -case eType_SHORT: -paramNode->setAttr( "Value",(int)pParam->m_Value.m_Short ); -break; -case eType_INT: -paramNode->setAttr( "Value",(int)pParam->m_Value.m_Int ); -break; -case eType_FLOAT: -paramNode->setAttr( "Value",pParam->m_Value.m_Float ); -break; -case eType_STRING: -paramNode->setAttr( "Value",pParam->m_Value.m_String ); -break; -case eType_FCOLOR: -paramNode->setAttr( "Value",Vec3(pParam->m_Value.m_Color[0],pParam->m_Value.m_Color[1],pParam->m_Value.m_Color[2]) ); -break; -case eType_VECTOR: -paramNode->setAttr( "Value",Vec3(pParam->m_Value.m_Vector[0],pParam->m_Value.m_Vector[1],pParam->m_Value.m_Vector[2]) ); -break; -} -} -} -} -*/ - -////////////////////////////////////////////////////////////////////////// -void CMaterial::AssignToEntity(IRenderNode* pEntity) -{ - assert(pEntity); - pEntity->SetMaterial(GetMatInfo()); -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterial::IsBreakable2D() const -{ - if ((GetFlags() & MTL_FLAG_NODRAW) != 0) - { - return false; - } - - const QString& surfaceTypeName = GetSurfaceTypeName(); - if (ISurfaceTypeManager* pSurfaceManager = GetIEditor()->Get3DEngine()->GetMaterialManager()->GetSurfaceTypeManager()) - { - ISurfaceType* pSurfaceType = pSurfaceManager->GetSurfaceTypeByName(surfaceTypeName.toUtf8().data()); - if (pSurfaceType && pSurfaceType->GetBreakable2DParams() != 0) - { - return true; - } - } - - int count = GetSubMaterialCount(); - for (int i = 0; i < count; ++i) - { - const CMaterial* pSub = GetSubMaterial(i); - if (!pSub) - { - continue; - } - if (pSub->IsBreakable2D()) - { - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetFromMatInfo(_smart_ptr pMatInfo) -{ - assert(pMatInfo); - - m_shaderName = ""; - - ClearMatInfo(); - SetModified(true); - - m_mtlFlags = pMatInfo->GetFlags(); - if (m_mtlFlags & MTL_FLAG_MULTI_SUBMTL) - { - // Create sub materials. - SetSubMaterialCount(pMatInfo->GetSubMtlCount()); - for (int i = 0; i < GetSubMaterialCount(); i++) - { - _smart_ptr pChildMatInfo = pMatInfo->GetSubMtl(i); - if (!pChildMatInfo) - { - continue; - } - - if (pChildMatInfo->GetFlags() & MTL_FLAG_PURE_CHILD) - { - CMaterial* existingChild = GetSubMaterial(i); - if (existingChild) - { - existingChild->SetFromMatInfo(pChildMatInfo); - } - else - { - CMaterial* pChild = new CMaterial(pChildMatInfo->GetName(), pChildMatInfo->GetFlags()); - pChild->SetFromMatInfo(pChildMatInfo); - SetSubMaterial(i, pChild); - } - } - else - { - CMaterial* pChild = GetIEditor()->GetMaterialManager()->LoadMaterial(pChildMatInfo->GetName()); - pChild->SetFromMatInfo(pChildMatInfo); - SetSubMaterial(i, pChild); - } - } - } - else - { - SetShaderItem(pMatInfo->GetShaderItem()); - - if (m_shaderItem.m_pShaderResources) - { - m_shaderResources = SInputShaderResources(m_shaderItem.m_pShaderResources); - } - if (m_shaderItem.m_pShader) - { - // Get name of template. - IShader* pTemplShader = m_shaderItem.m_pShader; - if (pTemplShader) - { - m_nShaderGenMask = pTemplShader->GetGenerationMask(); - } - } - m_shaderName = pMatInfo->GetShaderName(); - ISurfaceType* pSurfaceType = pMatInfo->GetSurfaceType(); - if (pSurfaceType) - { - m_surfaceType = pSurfaceType->GetName(); - } - else - { - m_surfaceType = ""; - } - } - - // Mark as not modified. - SetModified(false); - - // Material link names - if (const char* szLinkName = pMatInfo->GetMaterialLinkName()) - { - m_linkedMaterial = szLinkName; - } - - ////////////////////////////////////////////////////////////////////////// - // Assign mat info. - m_pMatInfo = pMatInfo; - m_pMatInfo->SetUserData(this); - AddRef(); // Let IMaterial keep a reference to us. -} - -////////////////////////////////////////////////////////////////////////// -int CMaterial::GetSubMaterialCount() const -{ - return m_subMaterials.size(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetSubMaterialCount(int nSubMtlsCount) -{ - RecordUndo("Multi Material Change"); - m_subMaterials.resize(nSubMtlsCount); - UpdateMatInfo(); - NotifyChanged(); -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterial::GetSubMaterial(int index) const -{ - const int nSubMats = m_subMaterials.size(); - assert(index >= 0 && index < nSubMats); - - if (index < 0 || index >= nSubMats) - { - return NULL; - } - - return m_subMaterials[index]; -} - -////////////////////////////////////////////////////////////////////////// -int CMaterial::FindMaterialIndex(const QString& name) -{ - for (int i = 0; i < m_subMaterials.size(); ++i) - { - if (m_subMaterials[i]->GetName().compare(name) == 0) - { - return i; - } - } - - return -1; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetSubMaterial(int nSlot, CMaterial* mtl) -{ - RecordUndo("Multi Material Change"); - assert(nSlot >= 0 && nSlot < m_subMaterials.size()); - if (mtl) - { - if (mtl->IsMultiSubMaterial()) - { - return; - } - if (mtl->IsPureChild()) - { - mtl->m_pParent = this; - } - } - - if (m_subMaterials[nSlot]) - { - m_subMaterials[nSlot]->m_pParent = NULL; - } - m_subMaterials[nSlot] = mtl; - - if (!m_subMaterials[nSlot]) - { - m_subMaterials.erase(m_subMaterials.begin() + nSlot); - } - - UpdateMatInfo(); - NotifyChanged(); -} - -////////////////////////////////////////////////////////////////////////// -// This method will populate for the material editor the name and tool tip of the -// different textures of the current material -//CVarBlock* CMaterial::UpdateTextureNames(AZStd::unordered_map& textureVarsMap) -CVarBlock* CMaterial::UpdateTextureNames(CSmartVariableArray textureVars[EFTT_MAX]) -{ - CVarBlock* pTextureSlots = new CVarBlock; - IShader* pTemplShader = m_shaderItem.m_pShader; - int nTech = max(0, m_shaderItem.m_nTechnique); - SShaderTexSlots* pShaderSlots = pTemplShader ? pTemplShader->GetUsedTextureSlots(nTech) : nullptr; - - for (EEfResTextures nTexSlot = EEfResTextures(0); nTexSlot < EFTT_MAX; nTexSlot = EEfResTextures(nTexSlot + 1)) - { - if (!MaterialHelpers::IsAdjustableTexSlot((EEfResTextures)nTexSlot)) - { // do not take into account virtual slots (such as smoothness - normal's alpha) - // in theory this case should not happen as it is filtered from the source list. - continue; - } - - IVariable* pVar = textureVars[nTexSlot].GetVar(); - SShaderTextureSlot* pSlot = pShaderSlots ? pShaderSlots->m_UsedTextureSlots[nTexSlot] : nullptr; - - // If slot is NULL, fall back to default name - name here is the context name (i.e. diffuse, normal..) - // and not the actual texture file name - pVar->SetName(pSlot && pSlot->m_Name.length() ? pSlot->m_Name.c_str() : MaterialHelpers::LookupTexName((EEfResTextures) nTexSlot)); - pVar->SetDescription(pSlot && pSlot->m_Description.length() ? pSlot->m_Description.c_str() : MaterialHelpers::LookupTexDesc((EEfResTextures)nTexSlot)); - - int flags = pVar->GetFlags(); - - // TODO: slot->m_TexType gives expected sampler type (2D vs Cube etc). Could check/extract this here. - - // Not sure why this needs COLLAPSED added again, but without this all the slots expand - flags |= IVariable::UI_COLLAPSED; - - //clear the auto-expand flag if there is no texture assigned. - SEfResTexture* pTextureRes = m_shaderResources.GetTextureResource(nTexSlot); - bool noTextureName = (!pTextureRes ? true : pTextureRes->m_Name.empty()); - - if (noTextureName) - { - flags &= ~IVariable::UI_AUTO_EXPAND; - } - - // if slot is NULL, but we have reflection information, this slot isn't used - make the variable invisible - // unless there's a texture in the slot - if (pShaderSlots && !pSlot && noTextureName) - { - flags |= IVariable::UI_INVISIBLE; - } - else - { - flags &= ~IVariable::UI_INVISIBLE; - } - - pVar->SetFlags(flags); - - pTextureSlots->AddVariable(pVar); - } - - return pTextureSlots; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::ClearAllSubMaterials() -{ - RecordUndo("Multi Material Change"); - for (int i = 0; i < m_subMaterials.size(); i++) - { - if (m_subMaterials[i]) - { - m_subMaterials[i]->m_pParent = NULL; - m_subMaterials[i] = NULL; - } - } - UpdateMatInfo(); - NotifyChanged(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::Validate() -{ - if (IsDummy()) - { - CErrorRecord err; - err.error = QObject::tr("Material %1 file not found").arg(GetName()); - err.pItem = this; - GetIEditor()->GetErrorReport()->ReportError(err); - } - // Reload shader. - LoadShader(); - - // Validate sub materials. - for (int i = 0; i < m_subMaterials.size(); i++) - { - if (m_subMaterials[i]) - { - m_subMaterials[i]->Validate(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::GatherUsedResources(CUsedResources& resources) -{ - if (!IsUsed()) - { - return; - } - - SInputShaderResources& sr = GetShaderResources(); - for (auto iter = sr.m_TexturesResourcesMap.begin(); iter != sr.m_TexturesResourcesMap.end(); ++iter) - { - SEfResTexture* pTexture = &iter->second; - if (!pTexture->m_Name.empty()) - { - resources.Add(pTexture->m_Name.c_str()); - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterial::CanModify(bool bSkipReadOnly) -{ - if (m_bDummyMaterial) - { - return false; - } - - if (IsPureChild() && GetParent()) - { - return GetParent()->CanModify(bSkipReadOnly); - } - - if (bSkipReadOnly) - { - // If read only or in pack, do not save. - if (m_scFileAttributes & (SCC_FILE_ATTRIBUTE_READONLY | SCC_FILE_ATTRIBUTE_INPAK)) - { - return false; - } - - // Managed file must be checked out. - if ((m_scFileAttributes & SCC_FILE_ATTRIBUTE_MANAGED) && !(m_scFileAttributes & SCC_FILE_ATTRIBUTE_CHECKEDOUT)) - { - return false; - } - } - else - { - // Only if in pack. - if (m_scFileAttributes & (SCC_FILE_ATTRIBUTE_INPAK)) - { - return false; - } - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterial::Save(bool bSkipReadOnly, const QString& fullPath) -{ - // Save our parent - if (IsPureChild()) - { - if (m_pParent) - { - return m_pParent->Save(bSkipReadOnly); - } - return false; - } - - if (m_mtlFlags & MTL_FLAG_UIMATERIAL) - { - return false; - } - - GetFileAttributes(); - - if (bSkipReadOnly && IsModified()) - { - // If read only or in pack, do not save. - if (m_scFileAttributes & (SCC_FILE_ATTRIBUTE_READONLY | SCC_FILE_ATTRIBUTE_INPAK)) - { - gEnv->pLog->LogError("Can't save material %s (read-only)", GetName().toUtf8().constData()); - } - - // Managed file must be checked out. - if ((m_scFileAttributes & SCC_FILE_ATTRIBUTE_MANAGED) && !(m_scFileAttributes & SCC_FILE_ATTRIBUTE_CHECKEDOUT)) - { - gEnv->pLog->LogError("Can't save material %s (need to check out)", GetName().toUtf8().constData()); - } - } - - if (!CanModify(bSkipReadOnly)) - { - return false; - } - - - // If filename is empty do not not save. - if (GetFilename().isEmpty()) - { - return false; - } - - // Save material XML to a file that corresponds to the material name with extension .mtl. - XmlNodeRef mtlNode = XmlHelpers::CreateXmlNode("Material"); - CBaseLibraryItem::SerializeContext ctx(mtlNode, false); - Serialize(ctx); - - bool saveSucceeded = false; - if (fullPath.isEmpty()) - { - // If no filepath was specified, get the filename using the relative path/unique identifier of this material - saveSucceeded = XmlHelpers::SaveXmlNode(GetIEditor()->GetFileUtil(), mtlNode, GetFilename().toUtf8().data()); - } - else - { - // If a filepath was specified, save to the specified location - saveSucceeded = XmlHelpers::SaveXmlNode(GetIEditor()->GetFileUtil(), mtlNode, fullPath.toUtf8().data()); - } - - if (saveSucceeded) - { - // If material successfully saved, clear modified flag. - SetModified(false); - for (int i = 0; i < GetSubMaterialCount(); ++i) - { - CMaterial* pSubMaterial = GetSubMaterial(i); - if (pSubMaterial) - { - pSubMaterial->SetModified(false); - } - } - } - else - { - AZ_Warning("Material Editor", false, "Material '%s' failed to save successfully. Check that the file is writable and has been successfully checked out in source control.", m_name.toUtf8().data()); - } - - return saveSucceeded; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::ClearMatInfo() -{ - m_pMatInfo = nullptr; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr CMaterial::GetMatInfo(bool bUseExistingEngineMaterial) -{ - if (!m_pMatInfo) - { - if (m_bDummyMaterial) - { - m_pMatInfo = GetIEditor()->Get3DEngine()->GetMaterialManager()->GetDefaultMaterial(); - AddRef(); // Always keep dummy materials. - return m_pMatInfo; - } - - if (!IsMultiSubMaterial() && !m_shaderItem.m_pShader) - { - LoadShader(); - } - - if (!IsPureChild()) - { - if (bUseExistingEngineMaterial) - { - m_pMatInfo = GetIEditor()->Get3DEngine()->GetMaterialManager()->FindMaterial(GetName().toUtf8().data()); - } - - if (!m_pMatInfo) - { - m_pMatInfo = GetIEditor()->Get3DEngine()->GetMaterialManager()->CreateMaterial(GetName().toUtf8().data(), m_mtlFlags); - } - } - else - { - // Pure child should not be registered with the name. - m_pMatInfo = GetIEditor()->Get3DEngine()->GetMaterialManager()->CreateMaterial("", m_mtlFlags); - m_pMatInfo->SetName(GetName().toUtf8().data()); - } - m_mtlFlags = m_pMatInfo->GetFlags(); - UpdateMatInfo(); - - if (m_pMatInfo->GetUserData() != this) - { - m_pMatInfo->SetUserData(this); - AddRef(); // Let IMaterial keep a reference to us. - } - } - - return m_pMatInfo; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::NotifyChanged() -{ - if (m_bIgnoreNotifyChange) - { - return; - } - - if (!CanModify() && !IsModified() && CUndo::IsRecording()) - { - // Display Warning message. - Warning("Modifying read only material %s\r\nChanges will not be saved!", GetName().toUtf8().data()); - } - - SetModified(); - - GetIEditor()->GetMaterialManager()->OnItemChanged(this); -} - -////////////////////////////////////////////////////////////////////////// -class CUndoMaterial - : public IUndoObject -{ -public: - CUndoMaterial(CMaterial* pMaterial, const char* undoDescription, bool bForceUpdate) - { - assert(pMaterial); - - // Stores the current state of this object. - m_undoDescription = undoDescription; - - m_bIsSubMaterial = pMaterial->IsPureChild(); - - if (m_bIsSubMaterial) - { - CMaterial* pParentMaterial = pMaterial->GetParent(); - assert(pParentMaterial && !pParentMaterial->IsPureChild()); - if (pParentMaterial && !pParentMaterial->IsPureChild()) - { - bool bFound = false; - const int subMaterialCount = pParentMaterial->GetSubMaterialCount(); - for (int i = 0; i < subMaterialCount; ++i) - { - CMaterial* pSubMaterial = pParentMaterial->GetSubMaterial(i); - if (pSubMaterial == pMaterial) - { - bFound = true; - m_subMaterialName = pSubMaterial->GetName(); - break; - } - } - assert(bFound); - m_mtlName = pParentMaterial->GetName(); - } - } - else - { - m_mtlName = pMaterial->GetName(); - } - - // Save material XML to a file that corresponds to the material name with extension .mtl. - m_undo = XmlHelpers::CreateXmlNode("Material"); - CBaseLibraryItem::SerializeContext ctx(m_undo, false); - pMaterial->Serialize(ctx); - m_bForceUpdate = bForceUpdate; - } - -protected: - virtual void Release() { delete this; }; - - virtual int GetSize() - { - return sizeof(*this) + m_undoDescription.length() + m_mtlName.length(); - } - - virtual QString GetDescription() { return m_undoDescription; }; - - virtual void Undo(bool bUndo) - { - CMaterial* pMaterial = GetMaterial(); - - assert(pMaterial); - if (!pMaterial) - { - return; - } - - if (bUndo) - { - // Save current object state. - m_redo = XmlHelpers::CreateXmlNode("Material"); - CBaseLibraryItem::SerializeContext ctx(m_redo, false); - pMaterial->Serialize(ctx); - } - - CBaseLibraryItem::SerializeContext ctx(m_undo, true); - ctx.bUndo = bUndo; - pMaterial->Serialize(ctx); - - if (m_bForceUpdate && bUndo) - { - GetIEditor()->GetMaterialManager()->OnUpdateProperties(pMaterial, true); - } - } - - virtual void Redo() - { - CMaterial* pMaterial = GetMaterial(); - - if (!pMaterial) - { - return; - } - - CBaseLibraryItem::SerializeContext ctx(m_redo, true); - ctx.bUndo = true; - pMaterial->Serialize(ctx); - - if (m_bForceUpdate) - { - GetIEditor()->GetMaterialManager()->OnUpdateProperties(pMaterial, true); - } - } - -private: - CMaterial* GetMaterial() - { - CMaterial* pMaterial = (CMaterial*)GetIEditor()->GetMaterialManager()->FindItemByName(m_mtlName); - assert(pMaterial); - - if (pMaterial && m_bIsSubMaterial) - { - bool bFound = false; - const int subMaterialCount = pMaterial->GetSubMaterialCount(); - for (int i = 0; i < subMaterialCount; ++i) - { - CMaterial* pSubMaterial = pMaterial->GetSubMaterial(i); - if (pSubMaterial && (pSubMaterial->GetName() == m_subMaterialName)) - { - bFound = true; - pMaterial = pSubMaterial; - break; - } - } - assert(bFound && pMaterial); - } - - return pMaterial; - } - - QString m_undoDescription; - QString m_mtlName; - bool m_bIsSubMaterial; - QString m_subMaterialName; - XmlNodeRef m_undo; - XmlNodeRef m_redo; - bool m_bForceUpdate; -}; - -////////////////////////////////////////////////////////////////////////// -void CMaterial::RecordUndo(const char* sText, bool bForceUpdate) -{ - if (CUndo::IsRecording()) - { - CUndo::Record(new CUndoMaterial(this, sText, bForceUpdate)); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::OnMakeCurrent() -{ - UpdateFileAttributes(false); - - // If Shader not yet loaded, load it now. - if (!m_shaderItem.m_pShader) - { - LoadShader(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetSurfaceTypeName(const QString& surfaceType) -{ - m_surfaceType = surfaceType; - UpdateMatInfo(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::Reload() -{ - if (IsPureChild()) - { - if (m_pParent) - { - m_pParent->Reload(); - } - return; - } - if (IsDummy()) - { - return; - } - - XmlNodeRef mtlNode = GetISystem()->LoadXmlFromFile(GetFilename().toUtf8().data()); - if (!mtlNode) - { - return; - } - CBaseLibraryItem::SerializeContext serCtx(mtlNode, true); - serCtx.bUndo = true; // Simulate undo. - Serialize(serCtx); - - // was called by Simulate undo. - //UpdateMatInfo(); - //NotifyChanged(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::LinkToMaterial(const QString& name) -{ - m_linkedMaterial = name; - UpdateMatInfo(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::DisableHighlightForFrame() -{ - SetHighlightFlags(0); -} - -static ColorF Interpolate(const ColorF& a, const ColorF& b, float phase) -{ - const float oneMinusPhase = 1.0f - phase; - return ColorF(b.r * phase + a.r * oneMinusPhase, - b.g * phase + a.g * oneMinusPhase, - b.b * phase + a.b * oneMinusPhase, - b.a * phase + a.a * oneMinusPhase); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::UpdateHighlighting() -{ - if (!(GetFlags() & MTL_FLAG_NODRAW)) - { - const CInputLightMaterial& original = m_shaderResources.m_LMaterial; - CInputLightMaterial lm = original; - - ColorF highlightColor(0.0f, 0.0f, 0.0f, 1.0f); - float highlightIntensity = 0.0f; - - MAKE_SURE(GetIEditor()->GetMaterialManager(), return ); - GetIEditor()->GetMaterialManager()->GetHighlightColor(&highlightColor, &highlightIntensity, m_highlightFlags); - - if (m_shaderItem.m_pShaderResources) - { - ColorF diffuseColor = Interpolate(original.m_Diffuse, highlightColor, highlightIntensity); - ColorF emissiveColor = Interpolate(original.m_Emittance, highlightColor, highlightIntensity); - ColorF specularColor = Interpolate(original.m_Specular, highlightColor, highlightIntensity); - - // [Shader System TO DO] remove this hard coded association! - m_shaderItem.m_pShaderResources->SetColorValue(EFTT_DIFFUSE, diffuseColor); - m_shaderItem.m_pShaderResources->SetColorValue(EFTT_SPECULAR, specularColor); - m_shaderItem.m_pShaderResources->SetColorValue(EFTT_EMITTANCE, emissiveColor); - - m_shaderItem.m_pShaderResources->UpdateConstants(m_shaderItem.m_pShader); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterial::SetHighlightFlags(int highlightFlags) -{ - m_highlightFlags = highlightFlags; - - UpdateHighlighting(); -} - - -void CMaterial::SetShaderItem(const SShaderItem& shaderItem) -{ - SAFE_RELEASE(m_shaderItem.m_pShader); - SAFE_RELEASE(m_shaderItem.m_pShaderResources); - - m_shaderItem = shaderItem; - if (m_shaderItem.m_pShader) - { - m_shaderItem.m_pShader->AddRef(); - } - if (m_shaderItem.m_pShaderResources) - { - m_shaderItem.m_pShaderResources->AddRef(); - } -} diff --git a/Code/Sandbox/Editor/Material/Material.h b/Code/Sandbox/Editor/Material/Material.h deleted file mode 100644 index b311744e14..0000000000 --- a/Code/Sandbox/Editor/Material/Material.h +++ /dev/null @@ -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 -#include -#include "BaseLibraryItem.h" -#include "Include/IEditorMaterial.h" -#include "Util/Variable.h" -#include - -// 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& 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 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 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 m_pMatInfo; - - XmlNodeRef m_publicVarsCache; - - //! Array of sub materials. - std::vector<_smart_ptr > 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 diff --git a/Code/Sandbox/Editor/Material/MaterialBrowser.cpp b/Code/Sandbox/Editor/Material/MaterialBrowser.cpp deleted file mode 100644 index e39a29a47d..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowser.cpp +++ /dev/null @@ -1,1792 +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 "MaterialBrowser.h" - -// Qt -#include - -// AzQtComponents -#include - -// AzToolsFramework -#include - -// Editor -#include "MaterialManager.h" -#include "Clipboard.h" -#include "MaterialImageListCtrl.h" -#include "StringDlg.h" - -AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING -#include -AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING - - -enum -{ - MENU_UNDEFINED = CMaterialImageListCtrl::MaterialBrowserWidgetActionsStart, - MENU_CUT, - MENU_COPY, - MENU_COPY_NAME, - MENU_PASTE, - MENU_EXPLORE, - MENU_DUPLICATE, - MENU_EXTRACT, - MENU_RENAME, - MENU_DELETE, - MENU_RESET, - MENU_ASSIGNTOSELECTION, - MENU_SELECTASSIGNEDOBJECTS, - MENU_NUM_SUBMTL, - MENU_ADDNEW, - MENU_ADDNEW_MULTI, - MENU_CONVERT_TO_MULTI, - MENU_SUBMTL_MAKE, - MENU_SUBMTL_CLEAR, - MENU_SAVE_TO_FILE, - MENU_SAVE_TO_FILE_MULTI, - MENU_MERGE, - - MENU_SCM_ADD, - MENU_SCM_CHECK_OUT, - MENU_SCM_UNDO_CHECK_OUT, - MENU_SCM_GET_LATEST, - MENU_SCM_GET_LATEST_TEXTURES, -}; - -static QAction* CreateTreeViewAction(const char* text, const QKeySequence& shortcut, QWidget* shortcutContext, MaterialBrowserWidget* widget, void (MaterialBrowserWidget::*slot)()) -{ - QAction* action = new QAction(text, shortcutContext); - action->setShortcut(shortcut); - QObject::connect(action, &QAction::triggered, widget, slot); - widget->addAction(action); - return action; -} - -////////////////////////////////////////////////////////////////////////// -MaterialBrowserWidget::MaterialBrowserWidget(QWidget* parent) - : QWidget(parent) - , m_ui(new Ui::MaterialBrowser) - , m_filterModel(new MaterialBrowserFilterModel(this)) -{ - using namespace AzToolsFramework::AssetBrowser; - - m_ui->setupUi(this); - - // create some permanent (for the life of this widget) actions for shortcut handling - m_cutAction = CreateTreeViewAction("Cut", QKeySequence::Cut, m_ui->treeView, this, &MaterialBrowserWidget::OnCut); - m_copyAction = CreateTreeViewAction("Copy", QKeySequence::Copy, m_ui->treeView, this, &MaterialBrowserWidget::OnCopy); - m_pasteAction = CreateTreeViewAction("Paste", QKeySequence::Paste, m_ui->treeView, this, &MaterialBrowserWidget::OnPaste); - m_duplicateAction = CreateTreeViewAction("Duplicate", QKeySequence(Qt::CTRL + Qt::Key_D), m_ui->treeView, this, &MaterialBrowserWidget::OnDuplicate); - m_deleteAction = CreateTreeViewAction("Delete", QKeySequence::Delete, m_ui->treeView, this, &MaterialBrowserWidget::DeleteItem); - m_renameItemAction = CreateTreeViewAction("Rename", Qt::Key_F2, m_ui->treeView, this, &MaterialBrowserWidget::OnRenameItem); - m_addNewMaterialAction = CreateTreeViewAction("Add New Material", Qt::Key_Insert, m_ui->treeView, this, &MaterialBrowserWidget::OnAddNewMaterial); - - MaterialBrowserWidgetBus::Handler::BusConnect(); - - // Get the asset browser model - AssetBrowserComponentRequestBus::BroadcastResult(m_assetBrowserModel, &AssetBrowserComponentRequests::GetAssetBrowserModel); - AZ_Assert(m_assetBrowserModel, "Failed to get filebrowser model"); - - // Set up the filter model - m_filterModel->setSourceModel(m_assetBrowserModel); - m_ui->treeView->setModel(m_filterModel.data()); - m_ui->treeView->SetThumbnailContext("MaterialBrowser"); - m_ui->treeView->SetShowSourceControlIcons(true); - - m_ui->m_searchWidget->Setup(true, false); - m_filterModel->SetSearchFilter(m_ui->m_searchWidget); - connect(m_ui->m_searchWidget->GetFilter().data(), &AssetBrowserEntryFilter::updatedSignal, m_filterModel.data(), &MaterialBrowserFilterModel::SearchFilterUpdated); - - // Call LoadState to initialize the AssetBrowserTreeView's QTreeViewStateSaver - // This must be done BEFORE StartRecordUpdateJobs(). A race condition from the update jobs was causing a 5-10% crash/hang when opening the Material Editor. - m_ui->treeView->SetName("MaterialBrowserTreeView"); - - // Override the AssetBrowserTreeView's custom context menu - disconnect(m_ui->treeView, &QWidget::customContextMenuRequested, 0, 0); - connect(m_ui->treeView, &QWidget::customContextMenuRequested, this, [=](const QPoint& point) - { - CMaterialBrowserRecord record; - TryGetSelectedRecord(record); - ShowContextMenu(record, point); - }); - - connect(m_ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MaterialBrowserWidget::OnSelectionChanged); - //Wait for the signal emitted on record update jobs finished, then we can restore the selection for the previous selected item - connect(this, SIGNAL(refreshSelection()), this, SLOT(OnRefreshSelection())); - - connect(this, SIGNAL(materialAdded()), this, SLOT(OnMaterialAdded())); - - m_bIgnoreSelectionChange = false; - m_bItemsValid = true; - - m_pMatMan = GetIEditor()->GetMaterialManager(); - m_pMatMan->AddListener(this); - m_pListener = NULL; - - m_viewType = VIEW_LEVEL; - m_pMaterialImageListCtrl = NULL; - m_pLastActiveMultiMaterial = 0; - - m_bNeedReload = false; - - m_bHighlightMaterial = false; - m_timeOfHighlight = 0; - - m_bShowOnlyCheckedOut = false; - - GetIEditor()->RegisterNotifyListener(this); -} - -////////////////////////////////////////////////////////////////////////// -MaterialBrowserWidget::~MaterialBrowserWidget() -{ - m_filterModel->CancelRecordUpdateJobs(); - m_filterModel->deleteLater(); - m_ui->treeView->SaveState(); - GetIEditor()->UnregisterNotifyListener(this); - - m_pMaterialImageListCtrl = NULL; - m_pMatMan->RemoveListener(this); - ClearItems(); - - if (m_bHighlightMaterial) - { - m_pMatMan->SetHighlightedMaterial(0); - } - - MaterialBrowserWidgetBus::Handler::BusDisconnect(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::ClearItems() -{ - m_bIgnoreSelectionChange = true; - - if (m_pMaterialImageListCtrl) - { - QMaterialImageListModel* materialModel = - qobject_cast(m_pMaterialImageListCtrl->model()); - Q_ASSERT(materialModel); - materialModel->DeleteAllItems(); - } - - m_pLastActiveMultiMaterial = nullptr; - m_delayedSelection = nullptr; - - m_bIgnoreSelectionChange = false; -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::TryLoadRecordMaterial(CMaterialBrowserRecord& record) -{ - // If material already loaded ignore. - if (record.m_material) - { - return; - } - - m_bIgnoreSelectionChange = true; - // Try to load material for it. - record.m_material = m_pMatMan->LoadMaterial(record.GetRelativeFilePath().c_str(), false); - - m_filterModel->SetRecord(record); - m_bIgnoreSelectionChange = false; -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::TickRefreshMaterials() -{ - if (m_bHighlightMaterial) - { - uint32 t = GetTickCount(); - if ((t - m_timeOfHighlight) > 300) - { - m_bHighlightMaterial = false; - m_pMatMan->SetHighlightedMaterial(0); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnEditorNotifyEvent(EEditorNotifyEvent event) -{ - switch (event) - { - case eNotify_OnIdleUpdate: - { - TickRefreshMaterials(); - } - break; - case eNotify_OnBeginLoad: - { - //Need to make sure the selection is cleared before clearing the record map - SetSelectedItem(nullptr, nullptr, true); - m_filterModel->ClearRecordMap(); - } - break; - case eNotify_OnCloseScene: - { - m_filterModel->ShowOnlyLevelMaterials(false, true); - ClearItems(); - m_ui->treeView->SaveState(); - //Need to make sure the selection is cleared before clearing the record map - SetSelectedItem(nullptr, nullptr, true); - m_filterModel->ClearRecordMap(); - } - break; - case eNotify_OnEndNewScene: - case eNotify_OnEndSceneOpen: - { - m_filterModel->ShowOnlyLevelMaterials(false, true); - m_filterModel->StartRecordUpdateJobs(); - if (m_ui->treeView->IsTreeViewSavingReady()) - { - m_ui->treeView->ApplyTreeViewSnapshot(); - } - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::SetSelectedItem(_smart_ptr material, const TMaterialBrowserRecords* pMarkedRecords, bool selectInTreeView) -{ - if (m_bIgnoreSelectionChange) - { - return; - } - - m_bIgnoreSelectionChange = true; - if (pMarkedRecords) - { - m_markedRecords = *pMarkedRecords; - } - else - { - m_markedRecords.clear(); - } - - m_pMatMan->SetCurrentFolder(""); - - _smart_ptr selectedMaterial = material; - if (material && material->IsPureChild()) - { - selectedMaterial = material->GetParent(); - } - - // Clear the delayed selection whenever a new material is selected - m_delayedSelection = nullptr; - - // In some cases, such as when SetSelectedItem is called from the material picker or the rollup bar, - // the material has not yet been selected in the tree-view, so that item must be selected here - bool validSelection = false; - if (selectInTreeView) - { - if (!selectedMaterial) - { - // Clear the current selection so that the upcoming call to RefreshSelected() - // doesn't try to refresh the previously selected material which may be invalid - m_ui->treeView->clearSelection(); - m_ui->treeView->setCurrentIndex(QModelIndex()); - } - else if (m_markedRecords.size() > 0) - { - QItemSelection selection; - for (CMaterialBrowserRecord record : m_markedRecords) - { - QModelIndex currentIndex = m_filterModel->GetIndexFromMaterial(record.m_material); - if (currentIndex.isValid()) - { - selection.push_back(QItemSelectionRange(currentIndex)); - validSelection = true; - } - } - m_ui->treeView->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); - } - else - { - QModelIndex currentIndex = m_filterModel->GetIndexFromMaterial(selectedMaterial); - if (currentIndex.isValid()) - { - m_ui->treeView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::ClearAndSelect); - validSelection = true; - - // Now that the parent material is selected in the browser, - // select the appropriate sub-material in the material preview window - if (selectedMaterial == material->GetParent()) - { - for (int i = 0; i < selectedMaterial->GetSubMaterialCount(); ++i) - { - if (material == selectedMaterial->GetSubMaterial(i)) - { - m_selectedSubMaterialIndex = i; - break; - } - } - } - } - else - { - // Hold on to a pointer to this material, listen for the MaterialFinishedProcessing event, - // and attempt to re-select this material if it finishes processing in the background - m_delayedSelection = selectedMaterial; - } - } - } - - RefreshSelected(); - - if (!selectedMaterial) - { - QModelIndex current = m_ui->treeView->currentIndex(); - QString path; - while (current.isValid()) - { - path = '/' + current.data().toString() + path; - current = current.parent(); - } - m_pMatMan->SetCurrentFolder((Path::GetEditingGameDataFolder() + path.toUtf8().data()).c_str()); - } - else - { - if (selectedMaterial->IsMultiSubMaterial() && m_selectedSubMaterialIndex >= 0) - { - selectedMaterial = selectedMaterial->GetSubMaterial(m_selectedSubMaterialIndex); - } - } - - if (m_pListener) - { - // Don't call the listener event if we attempted to select an item in the tree view and failed - // to prevent the material parameter editor from switching to a new material if it wasn't actually selected - if (!selectInTreeView || validSelection) - { - m_pListener->OnBrowserSelectItem(selectedMaterial, false); - } - //Update the selected item if no material is selected in tree view - else if (!selectedMaterial && selectInTreeView) - { - m_pListener->OnBrowserSelectItem(nullptr, false); - } - } - - m_timeOfHighlight = GetTickCount(); - m_pMatMan->SetHighlightedMaterial(selectedMaterial); - if (selectedMaterial) - { - m_bHighlightMaterial = true; - } - - std::vector<_smart_ptr > markedMaterials; - if (pMarkedRecords) - { - for (size_t i = 0; i < pMarkedRecords->size(); ++i) - { - markedMaterials.push_back((*pMarkedRecords)[i].m_material); - } - } - m_pMatMan->SetMarkedMaterials(markedMaterials); - - m_bIgnoreSelectionChange = false; -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::SelectItem(IDataBaseItem* pItem, [[maybe_unused]] IDataBaseItem* pParentItem) -{ - if (m_bIgnoreSelectionChange) - { - return; - } - - if (!pItem) - { - return; - } - - _smart_ptr material = static_cast(pItem); - SetSelectedItem(material, 0, true); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnDuplicate() -{ - GetIEditor()->GetMaterialManager()->Command_Merge(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnCut() -{ - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - if (found) - { - OnCopy(); - DeleteItem(record); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnCopyName() -{ - _smart_ptr pMtl = GetCurrentMaterial(); - if (pMtl) - { - CClipboard clipboard(this); - clipboard.PutString(pMtl->GetName(), "Material Name"); - } -} - -void MaterialBrowserWidget::ShowOnlyLevelMaterials(bool levelOnly) -{ - m_filterModel->ShowOnlyLevelMaterials(levelOnly); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnCopy() -{ - _smart_ptr pMtl = GetCurrentMaterial(); - if (pMtl) - { - CClipboard clipboard(this); - XmlNodeRef node = XmlHelpers::CreateXmlNode("Material"); - node->setAttr("Name", pMtl->GetName().toUtf8().data()); - CBaseLibraryItem::SerializeContext ctx(node, false); - ctx.bCopyPaste = true; - pMtl->Serialize(ctx); - clipboard.Put(node); - } -} - -////////////////////////////////////////////////////////////////////////// -bool MaterialBrowserWidget::CanPaste() const -{ - CClipboard clipboard(nullptr); - if (clipboard.IsEmpty()) - { - return false; - } - XmlNodeRef node = clipboard.Get(); - if (!node) - { - return false; - } - - if (strcmp(node->getTag(), "Material") == 0) - { - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnPaste() -{ - CClipboard clipboard(this); - if (clipboard.IsEmpty()) - { - return; - } - XmlNodeRef node = clipboard.Get(); - if (!node) - { - return; - } - - if (strcmp(node->getTag(), "Material") == 0) - { - if (!m_pMatMan->GetCurrentMaterial()) - { - GetIEditor()->GetMaterialManager()->Command_Create(); - } - - _smart_ptr pMtl = m_pMatMan->GetCurrentMaterial(); - if (pMtl) - { - // This is material node. - CBaseLibraryItem::SerializeContext serCtx(node, true); - serCtx.bCopyPaste = true; - serCtx.bUniqName = true; - pMtl->Serialize(serCtx); - - SelectItem(pMtl, NULL); - pMtl->Save(); - pMtl->Reload(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnAddNewMaterial() -{ - GetIEditor()->GetMaterialManager()->Command_Create(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnAddNewMultiMaterial() -{ - GetIEditor()->GetMaterialManager()->Command_CreateMulti(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnMergeMaterials() -{ - GetIEditor()->GetMaterialManager()->Command_Merge(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnConvertToMulti() -{ - GetIEditor()->GetMaterialManager()->Command_ConvertToMulti(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::DeleteItem() -{ - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - if (found) - { - DeleteItem(record); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnResetItem() -{ - if (QMessageBox::question(this, tr("Reset Material"), tr("Reset Material to default?")) == QMessageBox::Yes) - { - _smart_ptr pMtl = GetCurrentMaterial(); - int index; - - pMtl->GetSubMaterialCount() > 0 ? index = pMtl->GetSubMaterialCount() : index = 1; - - if (pMtl) - { - for (int i = 0; i < index; i++) - { - pMtl->GetSubMaterialCount() > 0 ? pMtl->GetSubMaterial(i)->Reload() : pMtl->Reload(); - TickRefreshMaterials(); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::DeleteItem(const CMaterialBrowserRecord& record) -{ - _smart_ptr pMtl = record.m_material; - if (pMtl) - { - if (m_selectedSubMaterialIndex >= 0) - { - pMtl = pMtl->GetSubMaterial(m_selectedSubMaterialIndex); - OnClearSubMtlSlot(pMtl); - } - else - { - GetIEditor()->GetMaterialManager()->Command_Delete(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnRenameItem() -{ - _smart_ptr pMtl = GetCurrentMaterial(); - if (!pMtl) - { - return; - } - - if (pMtl->IsPureChild()) - { - StringDlg dlg(tr("Enter New Sub-Material Name"), this); - dlg.SetString(pMtl->GetName()); - dlg.SetCheckCallback([this](QString name) -> bool - { - static const int MAX_REASONABLE_MATERIAL_NAME = 128; - if (name.length() >= MAX_REASONABLE_MATERIAL_NAME) - { - QMessageBox::warning(this, tr("Name too long"), tr("Please enter a name less than %1 characters").arg(MAX_REASONABLE_MATERIAL_NAME)); - return false; - } - return true; - }); - - if (dlg.exec() == QDialog::Accepted) - { - pMtl->SetName(dlg.GetString()); - pMtl->Save(); - pMtl->Reload(); - } - } - else - { - if ((pMtl->GetFileAttributes() & SCC_FILE_ATTRIBUTE_MANAGED) && - !(pMtl->GetFileAttributes() & SCC_FILE_ATTRIBUTE_CHECKEDOUT)) - { - if (QMessageBox::Cancel == QMessageBox::information(this, tr("Confirm"), tr("Only checked-out files can be renamed. Check out and mark for delete before rename it?"), QMessageBox::Ok | QMessageBox::Cancel)) - { - return; - } - } - - QFileInfo info(pMtl->GetFilename()); - QString filename = info.fileName(); - if (!CFileUtil::SelectSaveFile("Material Files (*.mtl)", "mtl", info.path(), filename)) - { - return; - } - - QString itemName = m_pMatMan->FilenameToMaterial(Path::GetRelativePath(filename)); - if (itemName.isEmpty()) - { - return; - } - - if (m_pMatMan->FindItemByName(itemName)) - { - Warning("Material with name %s already exist", itemName.toUtf8().data()); - return; - } - - if (pMtl->GetFileAttributes() & SCC_FILE_ATTRIBUTE_MANAGED) - { - if (pMtl->GetFileAttributes() & SCC_FILE_ATTRIBUTE_CHECKEDOUT) - { - if (QMessageBox::Cancel == QMessageBox::information(this, tr("Confirm"), tr("The original file will be marked for delete and the new named file will be marked for integration."), QMessageBox::Ok | QMessageBox::Cancel)) - { - return; - } - } - else - { - CFileUtil::CheckoutFile(pMtl->GetFilename().toUtf8().data(), this); - } - - if (!CFileUtil::RenameFile(pMtl->GetFilename().toUtf8().data(), filename.toUtf8().data())) - { - QMessageBox::critical(this, tr("Error"), tr("Could not rename file in Source Control.")); - } - } - - - // Delete file on disk. - if (!pMtl->GetFilename().isEmpty()) - { - QFile::remove(pMtl->GetFilename()); - } - pMtl->SetName(itemName); - pMtl->Save(); - SetSelectedItem(pMtl, 0, true); - } -} - - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnSetSubMtlCount(const CMaterialBrowserRecord& record) -{ - _smart_ptr pMtl = record.m_material; - if (!pMtl) - { - return; - } - - if (!pMtl->IsMultiSubMaterial()) - { - return; - } - - int num = pMtl->GetSubMaterialCount(); - bool ok = false; - num = QInputDialog::getInt(this, tr("Number of Sub Materials"), QStringLiteral(""), num, 0, MAX_SUB_MATERIALS, 1, &ok); - if (ok) - { - if (num != pMtl->GetSubMaterialCount()) - { - if (m_selectedSubMaterialIndex >= num) - { - m_selectedSubMaterialIndex = num - 1; - } - - CUndo undo("Set SubMtl Count"); - pMtl->SetSubMaterialCount(num); - - for (int i = 0; i < num; i++) - { - if (pMtl->GetSubMaterial(i) == 0) - { - // Allocate pure childs for all empty slots. - QString name; - name = QStringLiteral("SubMtl%1").arg(i + 1); - _smart_ptr pChild = new CMaterial(name, MTL_FLAG_PURE_CHILD); - pMtl->SetSubMaterial(i, pChild); - } - } - } - } -} - - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::DoSourceControlOp(CMaterialBrowserRecord& record, ESourceControlOp scmOp) -{ - if (!GetIEditor()->IsSourceControlAvailable()) - { - return; - } - - _smart_ptr pMtl = record.m_material; - - if (pMtl && pMtl->IsPureChild()) - { - pMtl = pMtl->GetParent(); - } - - if (scmOp == ESCM_IMPORT) // don't save unless you're doing an operation which writes. - { - if (pMtl && pMtl->IsModified()) - { - pMtl->Save(); - } - } - - QString path = pMtl ? pMtl->GetFilename() : QString(); - - if (path.isEmpty()) - { - return; - } - - bool bRes = true; - switch (scmOp) - { - case ESCM_IMPORT: - if (pMtl) - { - QStringList filenames; - int nTextures = pMtl->GetTextureFilenames(filenames); - for (int i = 0; i < nTextures; ++i) - { - CFileUtil::CheckoutFile(filenames[i].toUtf8().data(), this); - } - - bRes = CFileUtil::CheckoutFile(path.toUtf8().data(), this); - } - break; - case ESCM_CHECKOUT: - { - if (pMtl && (pMtl->GetFileAttributes() & SCC_FILE_ATTRIBUTE_BYANOTHER)) - { - AZStd::string otherUser("another user"); - AzToolsFramework::SourceControlFileInfo fileInfo; - if (CFileUtil::GetFileInfoFromSourceControl(pMtl->GetFilename().toUtf8().data(), fileInfo, this)) - { - // Sanity check the source control api reports the file is checked out by another - AZ_Assert(fileInfo.HasFlag(AzToolsFramework::SCF_OtherOpen), "File attributes reporting incorrectly"); - otherUser = fileInfo.m_StatusUser; - } - - if (QMessageBox::question(this, QString(), tr("This file is checked out by %1. Try to continue?").arg(otherUser.c_str())) != QMessageBox::Yes) - { - return; - } - } - bRes = CFileUtil::GetLatestFromSourceControl(path.toUtf8().data(), this); - if (bRes) - { - bRes = CFileUtil::CheckoutFile(path.toUtf8().data(), this); - } - } - break; - case ESCM_UNDO_CHECKOUT: - bRes = CFileUtil::RevertFile(path.toUtf8().data(), this); - break; - case ESCM_GETLATEST: - bRes = CFileUtil::GetLatestFromSourceControl(path.toUtf8().data(), this); - break; - case ESCM_GETLATESTTEXTURES: - if (pMtl) - { - QString message; - QStringList filenames; - int nTextures = pMtl->GetTextureFilenames(filenames); - for (int i = 0; i < nTextures; ++i) - { - bRes = CFileUtil::GetLatestFromSourceControl(filenames[i].toUtf8().data(), this); - message += Path::GetRelativePath(filenames[i], true) + (bRes ? " [OK]" : " [Fail]") + "\n"; - } - QMessageBox::information(this, QString(), message.isEmpty() ? tr("No files are affected") : message); - } - return; - } - - if (!bRes) - { - QMessageBox::critical(this, tr("Error"), tr("Source Control Operation Failed.\r\nCheck if Source Control Provider correctly setup and working directory is correct.")); - return; - } - - // force the cache to be rebuilt next time we repaint - record.InitializeSourceControlAttributes(); - m_filterModel->SetRecord(record); - - if (pMtl) - { - pMtl->Reload(); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnMakeSubMtlSlot(const CMaterialBrowserRecord& record) -{ - if (m_selectedSubMaterialIndex >= 0) - { - _smart_ptr parentMaterial = record.m_material; - if (parentMaterial && parentMaterial->IsMultiSubMaterial()) - { - const QString str = tr("Making new material will override material currently assigned to the slot %1 of %2\r\nMake new sub material?") - .arg(m_selectedSubMaterialIndex).arg(parentMaterial->GetName()); - if (QMessageBox::question(this, tr("Confirm Override"), str) == QMessageBox::Yes) - { - QString name = tr("SubMtl%1") - .arg(m_selectedSubMaterialIndex + 1); - _smart_ptr pMtl = new CMaterial(name, MTL_FLAG_PURE_CHILD); - parentMaterial->SetSubMaterial(m_selectedSubMaterialIndex, pMtl); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnClearSubMtlSlot(_smart_ptr subMaterial) -{ - if (subMaterial && m_selectedSubMaterialIndex >= 0) - { - _smart_ptr parentMaterial = subMaterial->GetParent(); - if (parentMaterial && parentMaterial->IsMultiSubMaterial()) - { - const QString str = tr("Clear Sub-Material Slot %1 of %2?").arg(m_selectedSubMaterialIndex).arg(parentMaterial->GetName()); - if (QMessageBox::question(this, tr("Clear Sub-Material"), str) == QMessageBox::Yes) - { - CUndo undo("Material Change"); - SetSubMaterial(parentMaterial, m_selectedSubMaterialIndex, 0); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::SetSubMaterial(_smart_ptr parentMaterial, int slot, _smart_ptr subMaterial) -{ - if (parentMaterial && parentMaterial->IsMultiSubMaterial()) - { - // If the last sub-material is being removed, select the 2nd to last sub-material - if (!subMaterial && slot == parentMaterial->GetSubMaterialCount() - 1) - { - m_selectedSubMaterialIndex = slot - 1; - } - parentMaterial->SetSubMaterial(slot, subMaterial); - } -} - - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnDataBaseItemEvent(IDataBaseItem* pItem, EDataBaseItemEvent event) -{ - if (m_bIgnoreSelectionChange) - { - return; - } - - if (!pItem) - { - return; - } - - - switch (event) - { - case EDB_ITEM_EVENT_ADD: - break; - case EDB_ITEM_EVENT_DELETE: - { - if (pItem) - { - //If the deleted item is selected, remove selection - CMaterial* pMtl = static_cast(pItem); - CMaterial* selectedMaterial = GetCurrentMaterial(); - if (selectedMaterial && selectedMaterial->IsPureChild()) - { - selectedMaterial = selectedMaterial->GetParent(); - } - if (pMtl == selectedMaterial) - { - SetSelectedItem(nullptr, nullptr, true); - } - } - } - break; - case EDB_ITEM_EVENT_CHANGED: - { - CMaterial* pMtl = static_cast(pItem); - CMaterial* selectedMaterial = GetCurrentMaterial(); - if (selectedMaterial && selectedMaterial->IsPureChild()) - { - selectedMaterial = selectedMaterial->GetParent(); - } - // If this is a sub material, refresh parent - if (pMtl->IsPureChild()) - { - pMtl = pMtl->GetParent(); - } - - if (pMtl == selectedMaterial) - { - if (pMtl->IsMultiSubMaterial()) - { - m_pLastActiveMultiMaterial = NULL; - } - RefreshSelected(); - } - m_bItemsValid = false; - } - break; - case EDB_ITEM_EVENT_SELECTED: - { - SelectItem(pItem, NULL); - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::SetImageListCtrl(CMaterialImageListCtrl* pCtrl) -{ - m_pMaterialImageListCtrl = pCtrl; - if (m_pMaterialImageListCtrl) - { - connect(m_pMaterialImageListCtrl->selectionModel(), &QItemSelectionModel::currentChanged, - this, &MaterialBrowserWidget::OnSubMaterialSelectedInPreviewPane); - - connect(m_pMaterialImageListCtrl, &QAbstractItemView::clicked, - this, &MaterialBrowserWidget::OnSubMaterialSelectedInPreviewPane); - - m_pMaterialImageListCtrl->SetMaterialBrowserWidget(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnSaveToFile(bool bMulti) -{ - _smart_ptr pCurrentMaterial = GetCurrentMaterial(); - if (pCurrentMaterial) - { - QString startPath = GetIEditor()->GetSearchPath(EDITOR_PATH_MATERIALS); - QString filename; - if (!CFileUtil::SelectSaveFile("Material Files (*.mtl)", "mtl", startPath, filename)) - { - return; - } - QFileInfo info(filename); - QString itemName = info.baseName(); - itemName = Path::MakeGamePath(itemName); - - if (m_pMatMan->FindItemByName(itemName)) - { - Warning("Material with name %s already exist", itemName.toUtf8().data()); - return; - } - int flags = pCurrentMaterial->GetFlags(); - if (bMulti) - { - flags |= MTL_FLAG_MULTI_SUBMTL; - } - - pCurrentMaterial->SetFlags(flags); - - if (pCurrentMaterial->IsDummy()) - { - pCurrentMaterial->ClearMatInfo(); - pCurrentMaterial->SetDummy(false); - } - pCurrentMaterial->SetModified(true); - pCurrentMaterial->Save(); - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::RefreshSelected() -{ - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - _smart_ptr pMtl = nullptr; - if (!found) - { - ClearImageListControlSelection(); - return; - } - else - { - pMtl = record.m_material; - } - - if (m_pMaterialImageListCtrl) - { - QMaterialImageListModel* materialModel = - qobject_cast(m_pMaterialImageListCtrl->model()); - Q_ASSERT(materialModel); - - materialModel->InvalidateMaterial(pMtl); - if (pMtl) - { - _smart_ptr pMultiMtl = nullptr; - if (pMtl->IsMultiSubMaterial()) - { - // It's possible that the currently selected sub-material index is beyond the range of the current multi-material if, for example, - // the last sub-material was selected but then the source .mtl file was changed to have fewer total sub-materials - if (m_selectedSubMaterialIndex >= pMtl->GetSubMaterialCount()) - { - // If that's the case, select the last sub-material - // If the sub-material count has dropped to 0, setting m_selectedSubMaterialIndex to -1 will cause the parent material to be selected - m_selectedSubMaterialIndex = pMtl->GetSubMaterialCount() - 1; - } - - pMultiMtl = pMtl; - if (m_selectedSubMaterialIndex >= 0) - { - pMtl = pMtl->GetSubMaterial(m_selectedSubMaterialIndex); - } - } - - if (m_pLastActiveMultiMaterial != pMultiMtl || pMultiMtl == nullptr) - { - // A new material was selected, so the previewer needs to be cleared - materialModel->DeleteAllItems(); - // If the new material was not a multi-material, add it to the previewer - if (pMultiMtl == nullptr) - { - materialModel->AddMaterial(pMtl); - } - } - - // If a new multi-material was selected - if (m_pLastActiveMultiMaterial != pMultiMtl && pMultiMtl != nullptr) - { - // Add all of its submaterials to the previewer - for (size_t i = 0; i < pMultiMtl->GetSubMaterialCount(); i++) - { - if (pMultiMtl->GetSubMaterial(i)) - { - materialModel->AddMaterial(pMultiMtl->GetSubMaterial(i), reinterpret_cast(i)); - } - } - m_pMaterialImageListCtrl->selectionModel()->clear(); - - // If a sub-material was selected in the material browser, select it in the previewer - QModelIndex modelIndex; - if (m_selectedSubMaterialIndex >= 0) - { - modelIndex = materialModel->index(m_selectedSubMaterialIndex, 0); - } - m_pMaterialImageListCtrl->selectionModel()->select(modelIndex, QItemSelectionModel::SelectCurrent); - } - - m_pMaterialImageListCtrl->SelectMaterial(pMtl); - m_pLastActiveMultiMaterial = pMultiMtl; - } - else - { - ClearSelection(materialModel); - } - } -} - -void MaterialBrowserWidget::ClearImageListControlSelection() -{ - QMaterialImageListModel* materialModel = - qobject_cast(m_pMaterialImageListCtrl->model()); - Q_ASSERT(materialModel); - - ClearSelection(materialModel); -} - -void MaterialBrowserWidget::ClearSelection(QMaterialImageListModel* materialModel) -{ - materialModel->DeleteAllItems(); - m_pLastActiveMultiMaterial = nullptr; -} - -////////////////////////////////////////////////////////////////////////// - -void MaterialBrowserWidget::AddContextMenuActionsMultiSelect(QMenu& menu) const -{ - int numMaterialsSelected = 0; - for (int i = 0; i < m_markedRecords.size(); ++i) - { - if (m_markedRecords[i].m_material) - { - ++numMaterialsSelected; - } - } - const QString itemsSelected = tr(" (%1 Materials Selected)").arg(numMaterialsSelected); - menu.addAction(itemsSelected)->setEnabled(false); - menu.addSeparator(); - - if (numMaterialsSelected >= 2) // ... and at least two materials - { - menu.addAction(tr("Merge"))->setData(MENU_MERGE); - } - else - { - menu.addAction(tr("Merge (Select two or more)"))->setEnabled(false); - } -} - -void MaterialBrowserWidget::AddContextMenuActionsNoSelection(QMenu& menu) const -{ - QAction* action = menu.addAction(tr("Paste")); - action->setShortcut(QKeySequence::Paste); - action->setData(MENU_PASTE); - action->setEnabled(CanPaste()); - - menu.addSeparator(); - menu.addAction(tr("Add New Material"))->setData(MENU_ADDNEW); - menu.addAction(tr("Add New Multi Material"))->setData(MENU_ADDNEW_MULTI); - if (GetIEditor()->IsSourceControlAvailable()) - { - menu.addSeparator(); - menu.addAction(tr("Source Control"))->setEnabled(false); - menu.addAction(tr("Check Out"))->setData(MENU_SCM_CHECK_OUT); - menu.addAction(tr("Undo Check Out"))->setData(MENU_SCM_UNDO_CHECK_OUT); - menu.addAction(tr("Get Latest Version"))->setData(MENU_SCM_GET_LATEST); - } -} - -void MaterialBrowserWidget::AddContextMenuActionsSingleSelection(QMenu& menu, _smart_ptr material) const -{ - if (material) - { - if (material->IsMultiSubMaterial()) - { - if (m_selectedSubMaterialIndex >= 0) - { - AddContextMenuActionsSubMaterial(menu, material, material->GetSubMaterial(m_selectedSubMaterialIndex)); - } - else - { - AddContextMenuActionsMultiMaterial(menu); - AddContextMenuActionsCommon(menu, material); - } - } - else if (material->IsPureChild()) - { - AddContextMenuActionsSubMaterial(menu, material->GetParent(), material); - } - else - { - AddContextMenuActionsSingleMaterial(menu); - AddContextMenuActionsCommon(menu, material); - } - } -} - -void MaterialBrowserWidget::AddContextMenuActionsSubMaterial(QMenu& menu, _smart_ptr parentMaterial, _smart_ptr subMaterial) const -{ - bool enabled = true; - - if (parentMaterial) - { - uint32 nFileAttr = parentMaterial->GetFileAttributes(); - if (nFileAttr & SCC_FILE_ATTRIBUTE_READONLY) - { - enabled = false; - } - } - - QAction* action = menu.addAction(tr("Reset sub-material to default")); - action->setData(MENU_SUBMTL_MAKE); - action->setEnabled(enabled); - - menu.addSeparator(); - - action = menu.addAction(tr("Cut")); - action->setShortcut(QKeySequence::Cut); - action->setData(MENU_CUT); - action->setEnabled(enabled); - - action = menu.addAction(tr("Copy")); - action->setShortcut(QKeySequence::Copy); - action->setData(MENU_COPY); - - action = menu.addAction(tr("Paste")); - action->setShortcut(QKeySequence::Paste); - action->setData(MENU_PASTE); - action->setEnabled(CanPaste() && enabled); - - action = menu.addAction(tr("Rename\tF2")); - action->setData(MENU_RENAME); - action->setEnabled(enabled); - - action = menu.addAction(tr("Delete")); - action->setData(MENU_SUBMTL_CLEAR); - action->setEnabled(enabled); -} - -void MaterialBrowserWidget::AddContextMenuActionsMultiMaterial(QMenu& menu) const -{ - menu.addAction(tr("Set Number of Sub-Materials"))->setData(MENU_NUM_SUBMTL); - menu.addSeparator(); -} - -void MaterialBrowserWidget::AddContextMenuActionsSingleMaterial(QMenu& menu) const -{ - menu.addAction(tr("Convert To Multi Material"))->setData(MENU_CONVERT_TO_MULTI); - menu.addSeparator(); -} - -void MaterialBrowserWidget::AddContextMenuActionsCommon(QMenu& menu, _smart_ptr material) const -{ - uint32 fileAttributes = material->GetFileAttributes(); - - bool modificationsEnabled = true; - if (fileAttributes & SCC_FILE_ATTRIBUTE_READONLY) - { - modificationsEnabled = false; - } - - QAction* action = menu.addAction(tr("Cut")); - action->setShortcut(QKeySequence::Cut); - action->setData(MENU_CUT); - action = menu.addAction(tr("Copy")); - action->setShortcut(QKeySequence::Copy); - action->setData(MENU_COPY); - action = menu.addAction(tr("Paste")); - action->setShortcut(QKeySequence::Paste); - action->setData(MENU_PASTE); - action->setEnabled(CanPaste() && modificationsEnabled); - menu.addAction(tr("Copy Path to Clipboard"))->setData(MENU_COPY_NAME); - if (fileAttributes & SCC_FILE_ATTRIBUTE_INPAK) - { - menu.addAction(tr("Extract"))->setData(MENU_EXTRACT); - } - else - { - menu.addAction(tr("Explore"))->setData(MENU_EXPLORE); - } - menu.addSeparator(); - action = menu.addAction(tr("Duplicate")); - action->setShortcut(tr("Ctrl+D")); - action->setData(MENU_DUPLICATE); - menu.addAction(tr("Rename\tF2"))->setData(MENU_RENAME); - action = menu.addAction(tr("Delete")); - action->setShortcut(QKeySequence::Delete); - action->setData(MENU_DELETE); - menu.addSeparator(); - menu.addAction(tr("Assign to Selected Objects"))->setData(MENU_ASSIGNTOSELECTION); - menu.addAction(tr("Select Assigned Objects"))->setData(MENU_SELECTASSIGNEDOBJECTS); - menu.addSeparator(); - - menu.addAction(tr("Add New Material"))->setData(MENU_ADDNEW); - menu.addAction(tr("Add New Multi Material"))->setData(MENU_ADDNEW_MULTI); - menu.addAction(tr("Merge (Select two or more)"))->setEnabled(false); - - AddContextMenuActionsSourceControl(menu, material, fileAttributes); -} - -void MaterialBrowserWidget::AddContextMenuActionsSourceControl(QMenu& menu, _smart_ptr material, uint32 fileAttributes) const -{ - if (GetIEditor()->IsSourceControlAvailable()) - { - menu.addSeparator(); - - if (fileAttributes & SCC_FILE_ATTRIBUTE_INPAK) - { - menu.addAction(tr(" Material In Pak (Read Only)"))->setEnabled(false); - } - else - { - menu.addAction(tr(" Source Control"))->setEnabled(false); - if (!(fileAttributes & SCC_FILE_ATTRIBUTE_MANAGED)) - { - menu.addAction(tr("Add To Source Control"))->setData(MENU_SCM_ADD); - } - } - QAction* action = nullptr; - if (fileAttributes & SCC_FILE_ATTRIBUTE_MANAGED) - { - action = menu.addAction(tr("Check Out")); - action->setData(MENU_SCM_CHECK_OUT); - action->setEnabled(fileAttributes & SCC_FILE_ATTRIBUTE_READONLY || fileAttributes & SCC_FILE_ATTRIBUTE_INPAK); - action = menu.addAction(tr("Undo Check Out")); - action->setData(MENU_SCM_UNDO_CHECK_OUT); - action->setEnabled(fileAttributes & SCC_FILE_ATTRIBUTE_CHECKEDOUT); - menu.addAction(tr("Get Latest Version"))->setData(MENU_SCM_GET_LATEST); - } - - if (material) - { - QStringList filenames; - int nTextures = material->GetTextureFilenames(filenames); - action = menu.addAction(tr("Get Textures")); - action->setData(MENU_SCM_GET_LATEST_TEXTURES); - action->setEnabled(nTextures > 0); - } - } -} - -void MaterialBrowserWidget::ShowContextMenu(const CMaterialBrowserRecord& record, const QPoint& point) -{ - _smart_ptr material = record.m_material; - - // Create pop up menu. - QMenu menu; - if (m_markedRecords.size() >= 2) // it makes sense when we have at least two items selected - { - AddContextMenuActionsMultiSelect(menu); - } - else if (!material) // click on root, background or folder - { - AddContextMenuActionsNoSelection(menu); - } - else - { - // When right-clicking a single item in the material browser, select the parent material that was clicked, rather than the currently selected sub-material - // The context menu for sub-materials will be handled by the image list control rather than the material browser widget - m_selectedSubMaterialIndex = -1; - SetSelectedItem(material, nullptr, true); - AddContextMenuActionsSingleSelection(menu, material); - } - QAction* action = menu.exec(m_ui->treeView->mapToGlobal(point)); - const int cmd = action ? action->data().toInt() : 0; - - OnContextMenuAction(cmd, material); -} - -void MaterialBrowserWidget::OnContextMenuAction(int command, _smart_ptr material) -{ - CMaterialBrowserRecord record; - TryGetSelectedRecord(record); - switch (command) - { - case MENU_UNDEFINED: - return; // do nothing - case MENU_CUT: - OnCut(); - break; - case MENU_COPY: - OnCopy(); - break; - case MENU_COPY_NAME: - OnCopyName(); - break; - case MENU_PASTE: - OnPaste(); - break; - case MENU_EXPLORE: - { - if (material && material->IsPureChild()) - { - material = material->GetParent(); - } - - if (material) - { - QString fullPath = material->GetFilename(); - AzQtComponents::ShowFileOnDesktop(fullPath); - } - } - break; - case MENU_EXTRACT: - { - if (material && material->IsPureChild()) - { - material = material->GetParent(); - } - - if (material) - { - QString fullPath = material->GetFilename(); - if (CFileUtil::ExtractFile(fullPath, true, fullPath.toUtf8().data())) - { - AzQtComponents::ShowFileOnDesktop(fullPath); - } - } - } - break; - case MENU_DUPLICATE: - OnDuplicate(); - break; - case MENU_RENAME: - OnRenameItem(); - break; - case MENU_DELETE: - DeleteItem(record); - break; - case MENU_RESET: - OnResetItem(); - break; - case MENU_ASSIGNTOSELECTION: - { - CUndo undo("Assign Material To Selection"); - GetIEditor()->GetMaterialManager()->Command_AssignToSelection(); - break; - } - case MENU_SELECTASSIGNEDOBJECTS: - { - CUndo undo("Select Objects With Current Material"); - GetIEditor()->GetMaterialManager()->Command_SelectAssignedObjects(); - break; - } - case MENU_NUM_SUBMTL: - OnSetSubMtlCount(record); - break; - case MENU_ADDNEW: - OnAddNewMaterial(); - break; - case MENU_ADDNEW_MULTI: - OnAddNewMultiMaterial(); - break; - case MENU_CONVERT_TO_MULTI: - OnConvertToMulti(); - break; - case MENU_MERGE: - OnMergeMaterials(); - break; - - case MENU_SUBMTL_MAKE: - OnMakeSubMtlSlot(record); - break; - case MENU_SUBMTL_CLEAR: - OnClearSubMtlSlot(material); - break; - - case MENU_SCM_ADD: - DoSourceControlOp(record, ESCM_IMPORT); - break; - case MENU_SCM_CHECK_OUT: - DoSourceControlOp(record, ESCM_CHECKOUT); - break; - case MENU_SCM_UNDO_CHECK_OUT: - DoSourceControlOp(record, ESCM_UNDO_CHECKOUT); - break; - case MENU_SCM_GET_LATEST: - DoSourceControlOp(record, ESCM_GETLATEST); - break; - case MENU_SCM_GET_LATEST_TEXTURES: - DoSourceControlOp(record, ESCM_GETLATESTTEXTURES); - break; - - case MENU_SAVE_TO_FILE: - OnSaveToFile(false); - break; - case MENU_SAVE_TO_FILE_MULTI: - OnSaveToFile(true); - break; - //case MENU_MAKE_SUBMTL: OnAddNewMultiMaterial(); break; - } -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::PopulateItems() -{ - if (m_bIgnoreSelectionChange) - { - return; - } - - if (m_bItemsValid) - { - return; - } - - m_bItemsValid = true; - m_bIgnoreSelectionChange = true; - - IDataBaseItem* pSelection = m_pMatMan->GetSelectedItem(); - IDataBaseItem* pSelectionParent = m_pMatMan->GetSelectedParentItem(); - - m_bIgnoreSelectionChange = false; - - if (pSelection) - { - SelectItem(pSelection, pSelectionParent); - if (m_bHighlightMaterial) - { - m_bHighlightMaterial = false; - m_pMatMan->SetHighlightedMaterial(0); - } - } -} - -void MaterialBrowserWidget::StartRecordUpdateJobs() -{ - m_filterModel->StartRecordUpdateJobs(); -} - -////////////////////////////////////////////////////////////////////////// -uint32 MaterialBrowserWidget::MaterialNameToCrc32(const QString& str) -{ - return CCrc32::ComputeLowercase(str.toUtf8()); -} - -////////////////////////////////////////////////////////////////////////// -bool MaterialBrowserWidget::TryGetSelectedRecord(CMaterialBrowserRecord& record) -{ - QVariant variant = m_filterModel->data(m_ui->treeView->currentIndex(), Qt::UserRole); - if (variant.isValid()) - { - record = variant.value(); - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -_smart_ptr MaterialBrowserWidget::GetCurrentMaterial() -{ - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - if (found && record.m_material) - { - if (record.m_material->IsMultiSubMaterial() && m_selectedSubMaterialIndex >= 0) - { - return record.m_material->GetSubMaterial(m_selectedSubMaterialIndex); - } - else - { - return record.m_material; - } - } - - return m_pMatMan->GetCurrentMaterial(); -} - -////////////////////////////////////////////////////////////////////////// -AZStd::string MaterialBrowserWidget::GetSelectedMaterialID() -{ - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - if (found) - { - return record.GetRelativeFilePath(); - } - return AZStd::string(); -} - -////////////////////////////////////////////////////////////////////////// -void MaterialBrowserWidget::OnSelectionChanged() -{ - m_selectedSubMaterialIndex = -1; - TMaterialBrowserRecords markedRecords; - - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - for (const QModelIndex& row : m_ui->treeView->selectionModel()->selectedRows()) - { - QVariant userRole = row.data(Qt::UserRole); - if (userRole.isValid()) - { - CMaterialBrowserRecord currentRecord = userRole.value(); - markedRecords.push_back(currentRecord); - } - } - - if (!found && !markedRecords.empty()) - { - record = markedRecords.front(); - found = true; - } - if (found) - { - // Since the call to SetSelectedItem is coming from an OnSelectionChanged event, the appropriate - // element of the tree view has already been selected. Pass in false for the selectInTreeView argument - // to prevent SetSelectedItem from trying to re-select the material in the browser - SetSelectedItem(record.m_material, &markedRecords, false); - } -} - -void MaterialBrowserWidget::OnRefreshSelection() -{ - // force RefreshSelected to repopulate by setting m_pLastActiveMultiMaterial to null - // so it thinks we selected a new material. - m_pLastActiveMultiMaterial = nullptr; - - //If no material is selected, clear preview. - if (!GetCurrentMaterial()) - { - if (m_pMaterialImageListCtrl) - { - QMaterialImageListModel* materialModel = - qobject_cast(m_pMaterialImageListCtrl->model()); - Q_ASSERT(materialModel); - materialModel->DeleteAllItems(); - } - } - - RefreshSelected(); - - // Force update the material dialog - if (m_pListener) - { - m_pListener->OnBrowserSelectItem(GetCurrentMaterial(), true); - } -} - -void MaterialBrowserWidget::OnMaterialAdded() -{ - if (m_delayedSelection) - { - SetSelectedItem(m_delayedSelection, nullptr, true); - - // Force update the material dialog - if (m_pListener) - { - m_pListener->OnBrowserSelectItem(GetCurrentMaterial(), true); - } - } -} - -void MaterialBrowserWidget::OnSubMaterialSelectedInPreviewPane(const QModelIndex& current) -{ - if (!m_pMaterialImageListCtrl) - { - return; - } - - QMaterialImageListModel* materialModel = - qobject_cast(m_pMaterialImageListCtrl->model()); - Q_ASSERT(materialModel); - - int nSlot = (INT_PTR)materialModel->UserDataFromIndex(current); - if (nSlot < 0) - { - return; - } - - CMaterialBrowserRecord record; - bool found = TryGetSelectedRecord(record); - if (!found || !record.m_material) - { - return; - } - - if (!record.m_material->IsMultiSubMaterial()) - { - return; // must be multi sub material. - } - if (nSlot >= record.m_material->GetSubMaterialCount()) - { - return; - } - - if (nSlot == m_selectedSubMaterialIndex) - { - return; - } - - m_selectedSubMaterialIndex = nSlot; - - SetSelectedItem(record.m_material, nullptr, false); -} - -void MaterialBrowserWidget::SaveCurrentMaterial() -{ - // Saving might open a modal dialog asking to overwrite, therefore don't run this from DTOR, might crash - - _smart_ptr pCurrentMtl = GetCurrentMaterial(); - if (pCurrentMtl && pCurrentMtl->IsModified()) - { - pCurrentMtl->Save(); - } -} - -void MaterialBrowserWidget::expandAllNotMatchingIndexes(const QModelIndex& parent) -{ - if (!parent.isValid()) - { - m_ui->treeView->collapseAll(); - } - - const int rowCount = m_ui->treeView->model()->rowCount(parent); - for (int row = 0; row < rowCount; ++row) - { - const QModelIndex index = m_ui->treeView->model()->index(row, 0, parent); - const QString text = index.data().toString(); - bool contains = true; - m_ui->treeView->setExpanded(index, !contains); - if (!contains) - { - expandAllNotMatchingIndexes(index); - } - } -} - -void MaterialBrowserWidget::MaterialAddFinished() -{ - emit materialAdded(); -} - -void MaterialBrowserWidget::MaterialFinishedProcessing(_smart_ptr material, const QPersistentModelIndex& filterModelIndex) -{ - // If the currently selected material finished processing - if (filterModelIndex.isValid() && filterModelIndex == m_ui->treeView->currentIndex()) - { - // Stash the delayed selection so that it is not cleared just because the currently selected material finished processing - _smart_ptr tempDelayedSelection = m_delayedSelection; - - // Re-select the material to update the material dialogue - // but ignore the tree-view selection since the current index is already the correct one for this material - SetSelectedItem(material, nullptr, false); - - // Force update the material dialog - if (m_pListener) - { - m_pListener->OnBrowserSelectItem(GetCurrentMaterial(), true); - } - - if (material != m_delayedSelection) - { - // If the current selection that just finished processing was not the delayed selection, restore the delayed selection - m_delayedSelection = tempDelayedSelection; - } - } - // If there was a failed attempt to select the material before it finished processing - else if (m_delayedSelection && m_delayedSelection == material) - { - // Re-select the material to update the material dialogue - // and also select the material in the tree-view - SetSelectedItem(material, nullptr, true); - - // Force update the material dialog - if (m_pListener) - { - m_pListener->OnBrowserSelectItem(GetCurrentMaterial(), true); - } - } -} - -void MaterialBrowserWidget::MaterialRecordUpdateFinished() -{ - //The event is sent by a AZJob working thread, need to emit a signal here for qt to catch later. - //It can make sure all the qt functions need to be called at this point are only executed in the qt thread. - emit refreshSelection(); -} - - -#include diff --git a/Code/Sandbox/Editor/Material/MaterialBrowser.h b/Code/Sandbox/Editor/Material/MaterialBrowser.h deleted file mode 100644 index d02045bacd..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowser.h +++ /dev/null @@ -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 -#include -#include -#include - -#include -#endif - -class CMaterial; - -class MaterialBrowserWidget; -class CMaterialImageListCtrl; -class QMaterialImageListModel; - -class QTreeView; -class QAction; - -struct IDataBaseItem; -class CMaterialBrowserRecord; -typedef std::vector 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 material) const; - void OnContextMenuAction(int command, _smart_ptr material); - - // MaterialBrowserWidgetBus event handlers - void MaterialAddFinished() override; - void MaterialFinishedProcessing(_smart_ptr 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 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 subMaterial); - void SetSubMaterial(_smart_ptr parentMaterial, int slot, _smart_ptr subMaterial); - - void OnSaveToFile(bool bMulti); - - void RefreshSelected(); - - void TickRefreshMaterials(); - void TryLoadRecordMaterial(CMaterialBrowserRecord &record); - - void ShowContextMenu(const CMaterialBrowserRecord &record, const QPoint& point); - _smart_ptr 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 parentMaterial, _smart_ptr subMaterial) const; - void AddContextMenuActionsMultiMaterial(QMenu &menu) const; - void AddContextMenuActionsSingleMaterial(QMenu &menu) const; - void AddContextMenuActionsCommon(QMenu &menu, _smart_ptr material) const; - void AddContextMenuActionsSourceControl(QMenu &menu, _smart_ptr material, uint32 fileAttributes) const; - - QScopedPointer m_ui; - - AzToolsFramework::AssetBrowser::AssetBrowserModel* m_assetBrowserModel; - QSharedPointer 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 m_pLastActiveMultiMaterial; - _smart_ptr 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 diff --git a/Code/Sandbox/Editor/Material/MaterialBrowser.ui b/Code/Sandbox/Editor/Material/MaterialBrowser.ui deleted file mode 100644 index 44e4e135ef..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowser.ui +++ /dev/null @@ -1,87 +0,0 @@ - - - MaterialBrowser - - - - 0 - 0 - 250 - 400 - - - - Form - - - - 0 - - - 2 - - - 0 - - - 0 - - - - - - - - 0 - 0 - - - - - 147 - 22 - - - - - - - - - - - 0 - 0 - - - - Qt::CustomContextMenu - - - QAbstractItemView::ExtendedSelection - - - false - - - - - - - - AzToolsFramework::AssetBrowser::SearchWidget - QWidget -
AzToolsFramework/AssetBrowser/Search/SearchWidget.h
- 1 -
- - AzToolsFramework::AssetBrowser::AssetBrowserTreeView - QTreeView -
AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h
-
-
- - - - -
diff --git a/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.cpp b/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.cpp deleted file mode 100644 index 9f145c4daf..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.cpp +++ /dev/null @@ -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 - -// AzToolsFramework -#include -#include -#include -#include - -// 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 products; - assetEntry->GetChildrenRecursively(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(modelIndex.internalPointer()); - - if (assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Source || - assetEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product) - { - AZStd::vector products; - assetEntry->GetChildrenRecursively(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(CFileUtil::GetAttributes(record.GetFullSourcePath().c_str(), false)); - record.m_lastCheckedSCCAttributes = QDateTime::currentDateTime(); - - // Update the record - m_materialRecordMap.erase(assetId); - m_materialRecordMap.insert(AZStd::pair(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(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(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& files) const -{ - GetRelativeFilePathsRecursive(files, this); -} - -void MaterialBrowserFilterModel::GetRelativeFilePathsRecursive(AZStd::vector& 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(modelIndex.internalPointer()); - - AZStd::vector products; - assetEntry->GetChildrenRecursively(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 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(modelIndex.internalPointer()); - - AZStd::vector products; - assetEntry->GetChildrenRecursively(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 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 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 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 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& 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 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& 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(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); - } -} diff --git a/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.h b/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.h deleted file mode 100644 index afb7f8a7ce..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowserFilterModel.h +++ /dev/null @@ -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 -#include -#include - -#include -#include -#include -#include -#include - - -#include -#include - -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 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; - -//! 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 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; - -/** -* 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 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 &files) const; - QModelIndex GetIndexFromMaterial(_smart_ptr 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 &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 m_materialRecordMap; - QVector 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& files, AZ::JobContext* context = nullptr); - void Process() override; -private: - MaterialBrowserFilterModel* m_filterModel; - AZStd::vector 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 &files, AZ::JobContext* context = nullptr); - void Process() override; -private: - MaterialBrowserFilterModel* m_filterModel; - AZStd::vector m_files; -}; - diff --git a/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.cpp b/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.cpp deleted file mode 100644 index cf2d3449d1..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.cpp +++ /dev/null @@ -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 foundRenderNodes; - unsigned int numFoundObjects = 0; - - numFoundObjects = GetIEditor()->Get3DEngine()->GetObjectsByFlags(0); - foundRenderNodes.resize(numFoundObjects, nullptr); - GetIEditor()->Get3DEngine()->GetObjectsByFlags(0, foundRenderNodes.data()); - - AZStd::vector<_smart_ptr> 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 diff --git a/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.h b/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.h deleted file mode 100644 index 4326e66218..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialBrowserSearchFilters.h +++ /dev/null @@ -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 -#include -#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 >; - MaterialMap m_localMap; -}; diff --git a/Code/Sandbox/Editor/Material/MaterialDialog.qrc b/Code/Sandbox/Editor/Material/MaterialDialog.qrc deleted file mode 100644 index c99e5b052a..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialDialog.qrc +++ /dev/null @@ -1,23 +0,0 @@ - - - images/material_browser_00.png - images/material_browser_01.png - images/material_browser_02.png - images/material_browser_03.png - images/material_00.png - images/material_01.png - images/material_02.png - images/material_03.png - images/material_04.png - images/material_05.png - images/material_06.png - images/material_07.png - images/filestatus_00.png - images/filestatus_01.png - images/filestatus_02.png - images/filestatus_03.png - images/filestatus_04.png - images/filestatus_05.png - images/filestatus_06.png - - diff --git a/Code/Sandbox/Editor/Material/MaterialHelpers.cpp b/Code/Sandbox/Editor/Material/MaterialHelpers.cpp deleted file mode 100644 index 8f9311a27a..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialHelpers.cpp +++ /dev/null @@ -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(pParam->m_Value.m_Byte); - break; - case eType_SHORT: - pIVar = new CVariable(pParam->m_Value.m_Short); - break; - case eType_INT: - pIVar = new CVariable(pParam->m_Value.m_Int); - break; - case eType_FLOAT: - pIVar = new CVariable(pParam->m_Value.m_Float); - break; - /* case eType_STRING: - pIVar = new CVariable(pParam->m_Value.m_String); - break; */ - case eType_FCOLOR: - pIVar = new CVariable(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(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(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* pVar = new CVariable; - 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; - } -} diff --git a/Code/Sandbox/Editor/Material/MaterialHelpers.h b/Code/Sandbox/Editor/Material/MaterialHelpers.h deleted file mode 100644 index 0f0228db7a..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialHelpers.h +++ /dev/null @@ -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); } -} diff --git a/Code/Sandbox/Editor/Material/MaterialImageListCtrl.cpp b/Code/Sandbox/Editor/Material/MaterialImageListCtrl.cpp deleted file mode 100644 index 6ebc85c1bc..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialImageListCtrl.cpp +++ /dev/null @@ -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 - -// 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 ResolveTerrainLayerPreviewMaterial(_smart_ptr material, _smart_ptr 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 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() << 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(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() << 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 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(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(model); - if (materialModel) - { - materialModel->SetPreviewModelCtrl(m_renderCtrl.data()); - } - - CImageListCtrl::setModel(model); - - auto delegate = qobject_cast(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(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(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() << 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() << Qt::DecorationRole); - } - } -} - -#include diff --git a/Code/Sandbox/Editor/Material/MaterialImageListCtrl.h b/Code/Sandbox/Editor/Material/MaterialImageListCtrl.h deleted file mode 100644 index fe9742fb53..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialImageListCtrl.h +++ /dev/null @@ -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 -#include "Material.h" -#include "IRenderer.h" // IAsyncTextureCompileListener -#include "IResourceCompilerHelper.h" -#include - -#include -#include -#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 m_largePreviewCtrl; // Used to draw the main 3D preview viewport for the selected sub-material - _smart_ptr m_largePreviewMaterial; - _smart_ptr m_tempTerrainMaterial; - QScopedPointer 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 m_pMatPreview; - QPointer m_renderCtrl; - QVector m_items; -}; - -#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALIMAGELISTCTRL_H diff --git a/Code/Sandbox/Editor/Material/MaterialLibrary.cpp b/Code/Sandbox/Editor/Material/MaterialLibrary.cpp deleted file mode 100644 index 351eee5c63..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialLibrary.cpp +++ /dev/null @@ -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(); -} diff --git a/Code/Sandbox/Editor/Material/MaterialLibrary.h b/Code/Sandbox/Editor/Material/MaterialLibrary.h deleted file mode 100644 index 5a80500e94..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialLibrary.h +++ /dev/null @@ -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 m_items; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -#endif // CRYINCLUDE_EDITOR_MATERIAL_MATERIALLIBRARY_H diff --git a/Code/Sandbox/Editor/Material/MaterialManager.cpp b/Code/Sandbox/Editor/Material/MaterialManager.cpp deleted file mode 100644 index 51460ff34a..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialManager.cpp +++ /dev/null @@ -1,2095 +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 "MaterialManager.h" - -// Qt -#include - -// AzCore -#include - -// AzFramework -#include - -// AzToolsFramework -#include -#include -#include - -// Editor -#include "MainWindow.h" -#include "MaterialLibrary.h" -#include "MaterialSender.h" -#include "MaterialUtils.h" -#include "ModelViewport.h" -#include "ISourceControl.h" -#include "UsedResources.h" -#include "Viewport.h" -#include "Commands/CommandManager.h" -#include "Include/IObjectManager.h" -#include "Objects/BaseObject.h" -#include "Objects/SelectionGroup.h" - - -static const char* MATERIALS_LIBS_PATH = "Materials/"; -static unsigned int s_highlightUpdateCounter = 0; - -// Convert a material name into a material identifier (no extension, no gamename, etc) so that it can be compared -// in the hash. -static QString UnifyMaterialName(const QString& source) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - azstrncpy(tempBuffer, AZ_ARRAY_SIZE(tempBuffer), source.toUtf8().data(), AZ_ARRAY_SIZE(tempBuffer) - 1); - MaterialUtils::UnifyMaterialName(tempBuffer); - return QString(tempBuffer); -} - -struct SHighlightMode -{ - float m_colorHue; - float m_period; - bool m_continuous; -}; - -static SHighlightMode g_highlightModes[] = { - { 0.70f, 0.8f, true }, // purple - { 0.25f, 0.75f, false }, // green - { 0.0, 0.75f, true } // red -}; - -class CMaterialHighlighter -{ -public: - void Start(CMaterial* pMaterial, int modeFlag); - void Stop(CMaterial* pMaterial, int modeFlag); - void GetHighlightColor(ColorF* color, float* intensity, int flags); - - void ClearMaterials() { m_materials.clear(); }; - void RestoreMaterials(); - void Update(); -private: - struct SHighlightOptions - { - int m_modeFlags; - }; - - typedef std::map Materials; - Materials m_materials; -}; - -AZStd::string DccMaterialToSourcePath(const AZStd::string& relativeDccMaterialPath) -{ - AZStd::string fullSourcePath; - bool sourcePathFound = false; - - // Get source path using relative .dccmtl path - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourcePathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativeDccMaterialPath, fullSourcePath); - - if (sourcePathFound) - { - // Set source path extension to ".mtl" - AzFramework::StringFunc::Path::ReplaceExtension(fullSourcePath, MATERIAL_FILE_EXT); - } - return fullSourcePath; -} - - -void CMaterialHighlighter::Start(CMaterial* pMaterial, int modeFlag) -{ - Materials::iterator it = m_materials.find(pMaterial); - if (it == m_materials.end()) - { - SHighlightOptions& options = m_materials[pMaterial]; - options.m_modeFlags = modeFlag; - } - else - { - SHighlightOptions& options = it->second; - options.m_modeFlags |= modeFlag; - } -} - -void CMaterialHighlighter::Stop(CMaterial* pMaterial, int modeFlag) -{ - if (pMaterial) - { - pMaterial->SetHighlightFlags(0); - } - - Materials::iterator it = m_materials.find(pMaterial); - if (it == m_materials.end()) - { - return; - } - - SHighlightOptions& options = it->second; - MAKE_SURE((options.m_modeFlags & modeFlag) != 0, return ); - - options.m_modeFlags &= ~modeFlag; - if (options.m_modeFlags == 0) - { - m_materials.erase(it); - } -} - -void CMaterialHighlighter::RestoreMaterials() -{ - for (Materials::iterator it = m_materials.begin(); it != m_materials.end(); ++it) - { - if (it->first) - { - it->first->SetHighlightFlags(0); - } - } -} - -void CMaterialHighlighter::Update() -{ - unsigned int counter = s_highlightUpdateCounter; - - Materials::iterator it; - for (it = m_materials.begin(); it != m_materials.end(); ++it) - { - // Only update each material every 4 frames - if (counter++ % 4 == 0) - { - it->first->SetHighlightFlags(it->second.m_modeFlags); - } - } - - s_highlightUpdateCounter = (s_highlightUpdateCounter + 1) % 4; -} - -void CMaterialHighlighter::GetHighlightColor(ColorF* color, float* intensity, int flags) -{ - MAKE_SURE(color != 0, return ); - MAKE_SURE(intensity != 0, return ); - - *intensity = 0.0f; - - if (flags == 0) - { - return; - } - - int flagIndex = 0; - while (flags) - { - if ((flags & 1) != 0) - { - break; - } - flags = flags >> 1; - ++flagIndex; - } - - MAKE_SURE(flagIndex < sizeof(g_highlightModes) / sizeof(g_highlightModes[0]), return ); - - const SHighlightMode& mode = g_highlightModes[flagIndex]; - float t = GetTickCount() / 1000.0f; - float h = mode.m_colorHue; - float s = 1.0f; - float v = 1.0f; - - color->fromHSV(h + sinf(t * g_PI2 * 5.0f) * 0.025f, s, v); - color->a = 1.0f; - - if (mode.m_continuous) - { - *intensity = fabsf(sinf(t * g_PI2 / mode.m_period)); - } - else - { - *intensity = max(0.0f, sinf(t * g_PI2 / mode.m_period)); - } -} - - -////////////////////////////////////////////////////////////////////////// -// CMaterialManager implementation. -////////////////////////////////////////////////////////////////////////// -CMaterialManager::CMaterialManager(CRegistrationContext& regCtx) - : m_pHighlighter(new CMaterialHighlighter) - , m_highlightMask(eHighlight_All) - , m_currentFolder("") - , m_joinThreads(false) -{ - m_bUniqGuidMap = false; - m_bUniqNameMap = true; - - m_bEditorUiReady = false; - m_bSourceControlErrorReported = false; - m_sourceControlFunctionQueued = false; - m_pLevelLibrary = (CBaseLibrary*)AddLibrary("Level", true); - - m_MatSender = new CMaterialSender(true); - - EBusFindAssetTypeByName materialResult("Material"); //from MaterialAssetTypeInfo.cpp, case insensitive - AZ::AssetTypeInfoBus::BroadcastResult(materialResult, &AZ::AssetTypeInfo::GetAssetType); - m_materialAssetType = materialResult.GetAssetType(); - - EBusFindAssetTypeByName dccMaterialResult("DccMaterial"); //from MaterialAssetTypeInfo.cpp, case insensitive - AZ::AssetTypeInfoBus::BroadcastResult(dccMaterialResult, &AZ::AssetTypeInfo::GetAssetType); - m_dccMaterialAssetType = dccMaterialResult.GetAssetType(); - - RegisterCommands(regCtx); - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler::BusConnect(); - AzFramework::AssetCatalogEventBus::Handler::BusConnect(); - AzToolsFramework::EditorEvents::Bus::Handler::BusConnect(); -} - -////////////////////////////////////////////////////////////////////////// -CMaterialManager::~CMaterialManager() -{ - AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler::BusDisconnect(); - AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); - AzToolsFramework::EditorEvents::Bus::Handler::BusDisconnect(); - - delete m_pHighlighter; - m_pHighlighter = 0; - - if (gEnv->p3DEngine) - { - gEnv->p3DEngine->GetMaterialManager()->SetListener(NULL); - } - - if (m_MatSender) - { - delete m_MatSender; - m_MatSender = 0; - } - - // Terminate thread that saves dcc materials. - m_joinThreads = true; - if (m_bEditorUiReady) - { - m_dccMaterialSaveSemaphore.release(); - m_dccMaterialSaveThread.join(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Set3DEngine() -{ - if (gEnv->p3DEngine) - { - gEnv->p3DEngine->GetMaterialManager()->SetListener(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::ClearAll() -{ - SetCurrentMaterial(NULL); - CBaseLibraryManager::ClearAll(); - - m_pLevelLibrary = (CBaseLibrary*)AddLibrary("Level", true); -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::CreateMaterial(const QString& sMaterialName,const XmlNodeRef& node, int nMtlFlags, [[maybe_unused]] unsigned long nLoadingFlags) -{ - CMaterial* pMaterial = new CMaterial(sMaterialName, nMtlFlags); - - if (node) - { - CBaseLibraryItem::SerializeContext serCtx(node, true); - serCtx.bUniqName = true; - pMaterial->Serialize(serCtx); - } - if (!pMaterial->IsPureChild() && !(pMaterial->GetFlags() & MTL_FLAG_UIMATERIAL)) - { - RegisterItem(pMaterial); - } - - return pMaterial; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::CreateMaterial(const char* sMaterialName,const XmlNodeRef& node, int nMtlFlags, unsigned long nLoadingFlags) -{ - return CreateMaterial(QString(sMaterialName), node, nMtlFlags, nLoadingFlags); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Export(XmlNodeRef& node) -{ - XmlNodeRef libs = node->newChild("MaterialsLibrary"); - for (int i = 0; i < GetLibraryCount(); i++) - { - IDataBaseLibrary* pLib = GetLibrary(i); - // Level libraries are saved in in level. - XmlNodeRef libNode = libs->newChild("Library"); - - // Export library. - libNode->setAttr("Name", pLib->GetName().toUtf8().data()); - } -} - -////////////////////////////////////////////////////////////////////////// -int CMaterialManager::ExportLib(CMaterialLibrary* pLib, XmlNodeRef& libNode) -{ - int num = 0; - // Export library. - libNode->setAttr("Name", pLib->GetName().toUtf8().data()); - libNode->setAttr("File", pLib->GetFilename().toUtf8().data()); - char version[50]; - GetIEditor()->GetFileVersion().ToString(version, AZ_ARRAY_SIZE(version)); - libNode->setAttr("SandboxVersion", version); - - // Serialize prototypes. - for (int j = 0; j < pLib->GetItemCount(); j++) - { - CMaterial* pMtl = (CMaterial*)pLib->GetItem(j); - - // Only export real used materials. - if (pMtl->IsDummy() || !pMtl->IsUsed() || pMtl->IsPureChild()) - { - continue; - } - - XmlNodeRef itemNode = libNode->newChild("Material"); - itemNode->setAttr("Name", pMtl->GetName().toUtf8().data()); - num++; - } - return num; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetSelectedItem(IDataBaseItem* pItem) -{ - m_pSelectedItem = (CBaseLibraryItem*)pItem; - SetCurrentMaterial((CMaterial*)pItem); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetCurrentMaterial(CMaterial* pMtl) -{ - if (m_pCurrentMaterial) - { - // Changing current material. save old one. - if (m_pCurrentMaterial->IsModified()) - { - m_pCurrentMaterial->Save(); - } - } - - m_pCurrentMaterial = pMtl; - if (m_pCurrentMaterial) - { - m_pCurrentMaterial->OnMakeCurrent(); - m_pCurrentEngineMaterial = m_pCurrentMaterial->GetMatInfo(); - } - else - { - m_pCurrentEngineMaterial = 0; - } - - m_pSelectedItem = pMtl; - m_pSelectedParent = pMtl ? pMtl->GetParent() : NULL; - - NotifyItemEvent(m_pCurrentMaterial, EDB_ITEM_EVENT_SELECTED); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetCurrentFolder(const QString& folder) -{ - m_currentFolder = folder; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetMarkedMaterials(const std::vector<_smart_ptr >& markedMaterials) -{ - m_markedMaterials = markedMaterials; -} - -void CMaterialManager::OnLoadShader(CMaterial* pMaterial) -{ - RemoveFromHighlighting(pMaterial, eHighlight_All); - AddForHighlighting(pMaterial); -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::GetCurrentMaterial() const -{ - return m_pCurrentMaterial; -} - -////////////////////////////////////////////////////////////////////////// -CBaseLibraryItem* CMaterialManager::MakeNewItem() -{ - CMaterial* pMaterial = new CMaterial("", 0); - return pMaterial; -} -////////////////////////////////////////////////////////////////////////// -CBaseLibrary* CMaterialManager::MakeNewLibrary() -{ - return new CMaterialLibrary(this); -} -////////////////////////////////////////////////////////////////////////// -QString CMaterialManager::GetRootNodeName() -{ - return "MaterialsLibs"; -} -////////////////////////////////////////////////////////////////////////// -QString CMaterialManager::GetLibsPath() -{ - if (m_libsPath.isEmpty()) - { - m_libsPath = MATERIALS_LIBS_PATH; - } - return m_libsPath; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::ReportDuplicateItem(CBaseLibraryItem* pItem, CBaseLibraryItem* pOldItem) -{ - QString sLibName; - if (pOldItem->GetLibrary()) - { - sLibName = pOldItem->GetLibrary()->GetName(); - } - CErrorRecord err; - err.pItem = (CMaterial*)pOldItem; - err.error = QObject::tr("Material %1 with the duplicate name to the loaded material %2 ignored").arg(pItem->GetName(), pOldItem->GetName()); - GetIEditor()->GetErrorReport()->ReportError(err); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Serialize([[maybe_unused]] XmlNodeRef& node, bool bLoading) -{ - //CBaseLibraryManager::Serialize( node,bLoading ); - if (bLoading) - { - } - else - { - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::OnEditorNotifyEvent(EEditorNotifyEvent event) -{ - CBaseLibraryManager::OnEditorNotifyEvent(event); - switch (event) - { - case eNotify_OnInit: - InitMatSender(); - break; - case eNotify_OnIdleUpdate: - m_pHighlighter->Update(); - break; - case eNotify_OnBeginGameMode: - m_pHighlighter->RestoreMaterials(); - break; - case eNotify_OnEndGameMode: - ReloadDirtyMaterials(); - break; - case eNotify_OnBeginNewScene: - SetCurrentMaterial(0); - break; - case eNotify_OnBeginSceneOpen: - SetCurrentMaterial(0); - break; - case eNotify_OnMissionChange: - SetCurrentMaterial(0); - break; - case eNotify_OnCloseScene: - SetCurrentMaterial(0); - m_pHighlighter->ClearMaterials(); - break; - case eNotify_OnQuit: - SetCurrentMaterial(0); - if (gEnv->p3DEngine) - { - gEnv->p3DEngine->GetMaterialManager()->SetListener(NULL); - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::ReloadDirtyMaterials() -{ - if (!GetIEditor()->Get3DEngine()) - { - return; - } - - IMaterialManager* runtimeMaterialManager = GetIEditor()->Get3DEngine()->GetMaterialManager(); - - uint32 mtlCount = 0; - - runtimeMaterialManager->GetLoadedMaterials(NULL, mtlCount); - - if (mtlCount > 0) - { - AZStd::vector<_smart_ptr> allMaterials; - - allMaterials.reserve(mtlCount); - - [[maybe_unused]] uint32 mtlCountPrev = mtlCount; - runtimeMaterialManager->GetLoadedMaterials(&allMaterials, mtlCount); - AZ_Assert(mtlCountPrev == mtlCount && mtlCount == allMaterials.size(), "It appears GetLoadedMaterials was not used correctly."); - - for (size_t i = 0; i < mtlCount; ++i) - { - _smart_ptr pMtl = allMaterials[i]; - if (pMtl && pMtl->IsDirty()) - { - runtimeMaterialManager->ReloadMaterial(pMtl); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::LoadMaterial(const QString& sMaterialName, bool bMakeIfNotFound) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - QString sMaterialNameClear = UnifyMaterialName(sMaterialName); - QString fullSourcePath = MaterialToFilename(sMaterialNameClear); - QString relativePath = PathUtil::ReplaceExtension(sMaterialNameClear.toUtf8().data(), MATERIAL_FILE_EXT).c_str(); - - return LoadMaterialInternal(sMaterialNameClear, fullSourcePath, relativePath, bMakeIfNotFound); -} - -////////////////////////////////////////////////////////////////////////// -XmlNodeRef CMaterialManager::LoadXmlNode(const QString &fullSourcePath, const QString &relativeFilePath) -{ - XmlNodeRef materialNode = GetISystem()->LoadXmlFromFile(fullSourcePath.toUtf8().data()); - if (!materialNode) - { - // try again with the product file in case its present - materialNode = GetISystem()->LoadXmlFromFile(relativeFilePath.toUtf8().data()); - } - return materialNode; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::LoadMaterialWithFullSourcePath(const QString& relativeFilePath, const QString& fullSourcePath, bool makeIfNotFound /*= true*/) -{ - QString materialNameClear = UnifyMaterialName(relativeFilePath); - return LoadMaterialInternal(materialNameClear, fullSourcePath, relativeFilePath, makeIfNotFound); -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::LoadMaterialInternal(const QString &materialNameClear, const QString &fullSourcePath, const QString &relativeFilePath, bool makeIfNotFound) -{ - // Note: We are loading from source files here, not from compiled assets, so there is no need to query the asset system for compilation status, etc. - - // Load material with this name if not yet loaded. - CMaterial* pMaterial = (CMaterial*)FindItemByName(materialNameClear); - if (pMaterial) - { - // If this is a dummy material that was created before for not found mtl file - // try reload the mtl file again to get valid material data. - if (pMaterial->IsDummy()) - { - XmlNodeRef mtlNode = GetISystem()->LoadXmlFromFile(fullSourcePath.toUtf8().data()); - if (mtlNode) - { - DeleteMaterial(pMaterial); - pMaterial = CreateMaterial(materialNameClear, mtlNode); - } - } - return pMaterial; - } - - XmlNodeRef mtlNode = LoadXmlNode(fullSourcePath, relativeFilePath); - - if (mtlNode) - { - pMaterial = CreateMaterial(materialNameClear, mtlNode); - } - else - { - if (makeIfNotFound) - { - pMaterial = new CMaterial(materialNameClear); - pMaterial->SetDummy(true); - RegisterItem(pMaterial); - - CErrorRecord err; - err.error = QObject::tr("Material %1 not found").arg(materialNameClear); - GetIEditor()->GetErrorReport()->ReportError(err); - } - } - - return pMaterial; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::LoadMaterial(const char* sMaterialName, bool bMakeIfNotFound) -{ - return LoadMaterial(QString(sMaterialName), bMakeIfNotFound); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::AddSourceFileOpeners(const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) -{ - using namespace AzToolsFramework; - using namespace AzToolsFramework::AssetBrowser; - - // disable if other project is active - if (AzFramework::Render::RenderSystemRequestBus::HasHandlers()) - { - return; - } - - if (AZStd::wildcard_match("*.mtl", fullSourceFileName)) - { - // we can handle these! - auto materialCallback = [this](const char* fullSourceFileNameInCall, const AZ::Uuid& sourceUUIDInCall) - { - const SourceAssetBrowserEntry* fullDetails = SourceAssetBrowserEntry::GetSourceByUuid(sourceUUIDInCall); - if (fullDetails) - { - CMaterial* materialFile = LoadMaterialWithFullSourcePath(QString::fromUtf8(fullDetails->GetRelativePath().c_str()), QString::fromUtf8(fullSourceFileNameInCall), false); - if (materialFile) - { - OpenViewPane("Material Editor"); - SetCurrentMaterial(materialFile); // the material browser pane should be able to deal with this. - } - } - }; - - openers.push_back({ "O3DE_MaterialEditor", "Open In Material Editor...", QIcon(), materialCallback }); - } -} - -////////////////////////////////////////////////////////////////////////// -static bool MaterialRequiresSurfaceType(CMaterial* pMaterial) -{ - // Do not enforce Surface Type... - - // ...over editor UI materials - if ((pMaterial->GetFlags() & MTL_FLAG_UIMATERIAL) != 0) - { - return false; - } - - // ...over SKY - if (pMaterial->GetShaderName() == "DistanceCloud" || - pMaterial->GetShaderName() == "Sky" || - pMaterial->GetShaderName() == "SkyHDR") - { - return false; - } - // ...over terrain materials - if (pMaterial->GetShaderName() == "Terrain.Layer") - { - return false; - } - // ...over vegetation - if (pMaterial->GetShaderName() == "Vegetation") - { - return false; - } - - // ...over decals - bool requiresSurfaceType = true; - CVarBlock* pShaderGenParams = pMaterial->GetShaderGenParamsVars(); - if (pShaderGenParams) - { - if (IVariable* pVar = pShaderGenParams->FindVariable("Decal")) - { - int value = 0; - pVar->Get(value); - if (value) - { - requiresSurfaceType = false; - } - } - // The function GetShaderGenParamsVars allocates a new CVarBlock object, so let's clean it up here - delete pShaderGenParams; - } - return requiresSurfaceType; -} - -////////////////////////////////////////////////////////////////////////// -int CMaterialManager::GetHighlightFlags(CMaterial* pMaterial) const -{ - if (pMaterial == NULL) - { - return 0; - } - - if ((pMaterial->GetFlags() & MTL_FLAG_NODRAW) != 0) - { - return 0; - } - - int result = 0; - - if (pMaterial == m_pHighlightMaterial) - { - result |= eHighlight_Pick; - } - - const QString& surfaceTypeName = pMaterial->GetSurfaceTypeName(); - if (surfaceTypeName.isEmpty() && MaterialRequiresSurfaceType(pMaterial)) - { - result |= eHighlight_NoSurfaceType; - } - - if (GetIEditor()->Get3DEngine()) - { - if (ISurfaceTypeManager* pSurfaceManager = GetIEditor()->Get3DEngine()->GetMaterialManager()->GetSurfaceTypeManager()) - { - const ISurfaceType* pSurfaceType = pSurfaceManager->GetSurfaceTypeByName(surfaceTypeName.toUtf8().data()); - if (pSurfaceType && pSurfaceType->GetBreakability() != 0) - { - result |= eHighlight_Breakable; - } - } - } - - return result; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::AddForHighlighting(CMaterial* pMaterial) -{ - if (pMaterial == NULL) - { - return; - } - - int highlightFlags = (GetHighlightFlags(pMaterial) & m_highlightMask); - if (highlightFlags != 0) - { - m_pHighlighter->Start(pMaterial, highlightFlags); - } - - int count = pMaterial->GetSubMaterialCount(); - for (int i = 0; i < count; ++i) - { - CMaterial* pChild = pMaterial->GetSubMaterial(i); - if (!pChild) - { - continue; - } - - AddForHighlighting(pChild); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::RemoveFromHighlighting(CMaterial* pMaterial, int mask) -{ - if (pMaterial == NULL) - { - return; - } - - m_pHighlighter->Stop(pMaterial, mask); - - int count = pMaterial->GetSubMaterialCount(); - for (int i = 0; i < count; ++i) - { - CMaterial* pChild = pMaterial->GetSubMaterial(i); - if (!pChild) - { - continue; - } - - RemoveFromHighlighting(pChild, mask); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::UpdateHighlightedMaterials() -{ - IDataBaseItemEnumerator* pEnum = CBaseLibraryManager::GetItemEnumerator(); - if (!pEnum) - { - return; - } - - CMaterial* pMaterial = (CMaterial*)pEnum->GetFirst(); - while (pMaterial) - { - RemoveFromHighlighting(pMaterial, eHighlight_All); - AddForHighlighting(pMaterial); - pMaterial = (CMaterial*)pEnum->GetNext(); - } - - pEnum->Release(); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::OnRequestMaterial(_smart_ptr pMatInfo) -{ - const char* pcName = pMatInfo->GetName(); - CMaterial* pMaterial = (CMaterial*) pMatInfo->GetUserData(); - - if (!pMaterial && pcName && *pcName) - { - pMaterial = LoadMaterial(pcName, false); - } - - if (pMaterial) - { - _smart_ptr pNewMatInfo = pMaterial->GetMatInfo(true); - assert(pNewMatInfo == pMatInfo); - //Only register if the material is not registered - if (!pMaterial->IsRegistered()) - { - RegisterItem(pMaterial); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::OnCreateMaterial(_smart_ptr pMatInfo) -{ - CMaterial* existingMaterial = static_cast(FindItemByName(UnifyMaterialName(pMatInfo->GetName()))); - bool materialAlreadyExists = existingMaterial != nullptr; - - // If its not a sub-material or a UI material - if (!(pMatInfo->GetFlags() & MTL_FLAG_PURE_CHILD) && !(pMatInfo->GetFlags() & MTL_FLAG_UIMATERIAL)) - { - // Create a new editor material if it doesn't exist - if (!materialAlreadyExists) - { - CMaterial* pMaterial = new CMaterial(pMatInfo->GetName()); - pMaterial->SetFromMatInfo(pMatInfo); - RegisterItem(pMaterial); - - AddForHighlighting(pMaterial); - } - else - { - // If the material already exists, re-set its values from the engine material that was just re-loaded - existingMaterial->SetFromMatInfo(pMatInfo); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::OnDeleteMaterial(_smart_ptr pMaterial) -{ - CMaterial* pMtl = (CMaterial*)pMaterial->GetUserData(); - if (pMtl) - { - RemoveFromHighlighting(pMtl, eHighlight_All); - DeleteMaterial(pMtl); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterialManager::IsCurrentMaterial(_smart_ptr pMaterial) const -{ - if (!pMaterial) - { - return false; - } - - CMaterial* pMtl = static_cast(pMaterial->GetUserData()); - bool currentMaterial = (pMtl == m_pCurrentMaterial); - - if (pMtl->GetParent()) - { - currentMaterial |= (pMtl->GetParent() == m_pCurrentMaterial); - } - - for (size_t subMatIdx = 0; subMatIdx < pMtl->GetMatInfo()->GetSubMtlCount(); ++subMatIdx) - { - if (static_cast(pMtl->GetMatInfo()->GetSubMtl(subMatIdx)->GetUserData()) == m_pCurrentMaterial) - { - currentMaterial = true; - break; - } - } - - return currentMaterial; -} - - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::FromIMaterial(_smart_ptr engineMaterial) -{ - if (!engineMaterial) - { - return nullptr; - } - CMaterial* editorMaterial = (CMaterial*)engineMaterial->GetUserData(); - if (!editorMaterial) - { - // If the user data isn't set, check for an existing material with the same name - editorMaterial = static_cast(FindItemByName(UnifyMaterialName(engineMaterial->GetName()))); - } - return editorMaterial; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SaveAllLibs() -{ -} - -////////////////////////////////////////////////////////////////////////// -QString CMaterialManager::FilenameToMaterial(const QString& filename) -{ - // Convert a full or relative path to a normalized name that can be used in a hash (so lowercase, relative path, correct slashes, remove extension) - // note that it may already be an asset path, if so, don't add the overhead of calling into the AP and convert it. - // if it starts with an alias (@) or if its an absolute file path, we need to convert it. Otherwise we really don't... - QString name = filename; - if (name.startsWith(QChar('@')) || AZ::IO::PathView(name.toUtf8().data()).IsAbsolute()) - { - name = Path::FullPathToGamePath(filename); // convert any full path to a relative path instead. - } - QByteArray n = name.toUtf8(); - MaterialUtils::UnifyMaterialName(n.data()); // Utility function used by all other parts of the code to unify slashes, lowercase, and remove extension - - return QString::fromUtf8(n); -} - -////////////////////////////////////////////////////////////////////////// -QString CMaterialManager::MaterialToFilename(const QString& sMaterialName) -{ - QString materialWithExtension = Path::ReplaceExtension(sMaterialName, MATERIAL_FILE_EXT); - QString fileName = Path::GamePathToFullPath(materialWithExtension); - const int mtlExtensionLength = strlen(MATERIAL_FILE_EXT); - if (fileName.right(mtlExtensionLength).toLower() != MATERIAL_FILE_EXT) - { - // we got something back which is not a mtl, fall back heuristic: - AZStd::string pathName(fileName.toUtf8().data()); - AZStd::string fileNameOfMaterial; - AzFramework::StringFunc::Path::StripFullName(pathName); // remove the filename of the path to the FBX file so now it just contains the folder of the fbx file. - AzFramework::StringFunc::Path::GetFullFileName(materialWithExtension.toUtf8().data(), fileNameOfMaterial); // remove the path part of the material so it only contains the file name - AZStd::string finalName; - AzFramework::StringFunc::Path::Join(pathName.c_str(), fileNameOfMaterial.c_str(), finalName); - fileName = finalName.c_str(); - } - return fileName; -} - -////////////////////////////////////////////////////////////////////////// -const AZ::Data::AssetType& CMaterialManager::GetMaterialAssetType() -{ - return m_materialAssetType; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::DeleteMaterial(CMaterial* pMtl) -{ - assert(pMtl); - _smart_ptr _ref(pMtl); - if (pMtl == GetCurrentMaterial()) - { - SetCurrentMaterial(NULL); - } - - DeleteItem(pMtl); - - // Delete it from all sub materials. - for (int i = 0; i < m_pLevelLibrary->GetItemCount(); i++) - { - CMaterial* pMultiMtl = (CMaterial*)m_pLevelLibrary->GetItem(i); - if (pMultiMtl->IsMultiSubMaterial()) - { - for (int slot = 0; slot < pMultiMtl->GetSubMaterialCount(); slot++) - { - if (pMultiMtl->GetSubMaterial(slot) == pMultiMtl) - { - // Clear this sub material slot. - pMultiMtl->SetSubMaterial(slot, 0); - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::RemoveMaterialFromDisk(const char * fileName) -{ - using namespace AzToolsFramework; - if (fileName) - { - SourceControlCommandBus::Broadcast(&SourceControlCommandBus::Events::RequestDelete, fileName, - [](bool success, const SourceControlFileInfo& info) - { - //If the file is not managed by source control, delete it locally - if (!success && !info.IsManaged()) - { - QFile::remove(info.m_filePath.c_str()); - } - } - ); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::RegisterCommands(CRegistrationContext& regCtx) -{ - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "duplicate", "", "", AZStd::bind(&CMaterialManager::Command_Duplicate, this)); - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "merge", "", "", AZStd::bind(&CMaterialManager::Command_Merge, this)); - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "delete", "", "", AZStd::bind(&CMaterialManager::Command_Delete, this)); - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "assign_to_selection", "", "", AZStd::bind(&CMaterialManager::Command_AssignToSelection, this)); - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "select_assigned_objects", "", "", AZStd::bind(&CMaterialManager::Command_SelectAssignedObjects, this)); - CommandManagerHelper::RegisterCommand(regCtx.pCommandManager, "material", "select_from_object", "", "", AZStd::bind(&CMaterialManager::Command_SelectFromObject, this)); -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterialManager::SelectSaveMaterial(QString& itemName, QString& fullSourcePath, const char* defaultStartPath) -{ - QString startPath; - if (defaultStartPath && defaultStartPath[0] != '\0') - { - startPath = defaultStartPath; - } - else - { - startPath = GetIEditor()->GetSearchPath(EDITOR_PATH_MATERIALS); - } - - if (!CFileUtil::SelectSaveFile("Material Files (*.mtl)", "mtl", startPath, fullSourcePath)) - { - return false; - } - - itemName = FilenameToMaterial(fullSourcePath); - if (itemName.isEmpty()) - { - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::SelectNewMaterial(int nMtlFlags, [[maybe_unused]] const char* sStartPath) -{ - QString path = m_pCurrentMaterial ? Path::GetPath(m_pCurrentMaterial->GetFilename()) : m_currentFolder; - QString itemName; - QString fullPath; - if (!SelectSaveMaterial(itemName, fullPath, path.toUtf8().data())) - { - return 0; - } - - if (FindItemByName(itemName)) - { - Warning("Material with name %s already exist", itemName.toUtf8().data()); - return 0; - } - - _smart_ptr mtl = CreateMaterial(itemName, XmlNodeRef(), nMtlFlags); - mtl->Update(); - bool skipReadOnly = true; - mtl->Save(skipReadOnly, fullPath); - SetCurrentMaterial(mtl); - return mtl; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_Create() -{ - SelectNewMaterial(0); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_CreateMulti() -{ - SelectNewMaterial(MTL_FLAG_MULTI_SUBMTL); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_ConvertToMulti() -{ - CMaterial* pMaterial = GetCurrentMaterial(); - - if (pMaterial && pMaterial->GetSubMaterialCount() == 0) - { - CMaterial* pSubMat = new CMaterial(*pMaterial); - pSubMat->SetName(pSubMat->GetShortName()); - pSubMat->SetFlags(pSubMat->GetFlags() | MTL_FLAG_PURE_CHILD); - - pMaterial->SetFlags(MTL_FLAG_MULTI_SUBMTL); - pMaterial->SetSubMaterialCount(1); - pMaterial->SetSubMaterial(0, pSubMat); - - pMaterial->Save(); - pMaterial->Reload(); - SetSelectedItem(pSubMat); - } - else - { - Warning(pMaterial ? "azlmbr.legacy.material.convert_to_multi called on invalid material setup" : "azlmbr.legacy.material.convert_to_multi called while no material selected"); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_Duplicate() -{ - CMaterial* pSrcMtl = GetCurrentMaterial(); - - if (!pSrcMtl) - { - CErrorRecord err; - err.error = "azlmbr.legacy.material.duplicate called while no materials selected"; - GetIEditor()->GetErrorReport()->ReportError(err); - return; - } - - if (GetIEditor()->IsSourceControlAvailable()) - { - uint32 attrib = pSrcMtl->GetFileAttributes(); - - if ((attrib & SCC_FILE_ATTRIBUTE_INPAK) && (attrib & SCC_FILE_ATTRIBUTE_MANAGED) && !(attrib & SCC_FILE_ATTRIBUTE_NORMAL)) - { - // Get latest for making folders with right case - CFileUtil::GetLatestFromSourceControl(pSrcMtl->GetFilename().toUtf8().data()); - } - } - - if (pSrcMtl != 0 && !pSrcMtl->IsPureChild()) - { - QString newUniqueRelativePath = MakeUniqueItemName(pSrcMtl->GetName()); - - // Create a new material. - _smart_ptr pMtl = DuplicateMaterial(newUniqueRelativePath.toUtf8().data(), pSrcMtl); - if (pMtl) - { - // Get the new filename from the relative path - AZStd::string newFileName; - AzFramework::StringFunc::Path::GetFileName(newUniqueRelativePath.toUtf8().data(), newFileName); - - // Get the full path to the original material, so we know which folder to put the new material in - AZStd::string newFullFilePath = pSrcMtl->GetFilename().toUtf8().data(); - - // Replace the original material filename with the filename from the new relative path + the material file extension to get the new full file path - AzFramework::StringFunc::Path::ReplaceFullName(newFullFilePath, newFileName.c_str(), MATERIAL_FILE_EXT); - - AzFramework::StringFunc::Path::Normalize(newFullFilePath); - - const bool skipReadOnly = true; - pMtl->Save(skipReadOnly, newFullFilePath.c_str()); - SetSelectedItem(pMtl); - } - } -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CMaterialManager::DuplicateMaterial(const char* newName, CMaterial* pOriginal) -{ - if (!newName) - { - assert(0 && "NULL newName passed into CMaterialManager::DuplicateMaterial"); - return 0; - } - if (!pOriginal) - { - assert(0 && "NULL pOriginal passed into CMaterialManager::DuplicateMaterial"); - return 0; - } - - - XmlNodeRef node = GetISystem()->CreateXmlNode("Material"); - CBaseLibraryItem::SerializeContext ctx(node, false); - ctx.bCopyPaste = true; - pOriginal->Serialize(ctx); - - return CreateMaterial(newName, node, pOriginal->GetFlags()); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::GenerateUniqueSubmaterialName(const CMaterial* pSourceMaterial, const CMaterial* pTargetMaterial, QString& uniqueSubmaterialName) const -{ - QString sourceMaterialName = pSourceMaterial->GetName(); - - // We don't need the whole path to the material, just the base name - QFileInfo filename(sourceMaterialName); - sourceMaterialName = filename.baseName(); - - uniqueSubmaterialName = sourceMaterialName; - size_t nameIndex = 0; - - bool nameUpdated = true; - while (nameUpdated) - { - nameUpdated = false; - for (size_t k = 0; k < pTargetMaterial->GetSubMaterialCount(); ++k) - { - CMaterial* pSubMaterial = pTargetMaterial->GetSubMaterial(k); - if (pSubMaterial && pSubMaterial->GetName() == uniqueSubmaterialName) - { - ++nameIndex; - uniqueSubmaterialName = QStringLiteral("%1%2").arg(sourceMaterialName).arg(nameIndex, 2, 10, QLatin1Char('0')); - nameUpdated = true; - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMaterialManager::DuplicateAsSubMaterialAtIndex(CMaterial* pSourceMaterial, CMaterial* pTargetMaterial, int subMaterialIndex) -{ - if (pSourceMaterial && pTargetMaterial && pTargetMaterial->GetSubMaterialCount() > subMaterialIndex) - { - // Resolve name collisions between the source material and the submaterials in the target material - QString newSubMaterialName; - GenerateUniqueSubmaterialName(pSourceMaterial, pTargetMaterial, newSubMaterialName); - - // Mark the material to be duplicated as a PURE_CHILD since it is being duplicated as a submaterial - int sourceMaterialFlags = pSourceMaterial->GetFlags(); - pSourceMaterial->SetFlags(sourceMaterialFlags | MTL_FLAG_PURE_CHILD); - - CMaterial* pNewSubMaterial = DuplicateMaterial(newSubMaterialName.toUtf8().data(), pSourceMaterial); - pTargetMaterial->SetSubMaterial(subMaterialIndex, pNewSubMaterial); - - // Reset the flags of the source material to their original values - pSourceMaterial->SetFlags(sourceMaterialFlags); - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_Merge() -{ - QString itemName; - QString fullPath; - QString defaultMaterialPath; - if (m_pCurrentMaterial) - { - defaultMaterialPath = Path::GetPath(m_pCurrentMaterial->GetFilename()); - } - if (!SelectSaveMaterial(itemName, fullPath, defaultMaterialPath.toUtf8().data())) - { - return; - } - - _smart_ptr pNewMaterial = CreateMaterial(itemName, XmlNodeRef(), MTL_FLAG_MULTI_SUBMTL); - - size_t totalSubMaterialCount = 0; - for (_smart_ptr pMaterial : m_markedMaterials) - { - if (pMaterial->IsMultiSubMaterial()) - { - totalSubMaterialCount += pMaterial->GetSubMaterialCount(); - } - else - { - totalSubMaterialCount++; - } - } - pNewMaterial->SetSubMaterialCount(totalSubMaterialCount); - - size_t subMaterialIndex = 0; - for (_smart_ptr pMaterial : m_markedMaterials) - { - if (pMaterial->IsMultiSubMaterial()) - { - // Loop through each submaterial and duplicate it as a submaterial in the new material - for (size_t j = 0; j < pMaterial->GetSubMaterialCount(); ++j) - { - CMaterial* pSubMaterial = pMaterial->GetSubMaterial(j); - if (DuplicateAsSubMaterialAtIndex(pSubMaterial, pNewMaterial, subMaterialIndex)) - { - ++subMaterialIndex; - } - } - } - else - { - // Duplicate the material as a submaterial in the new material - if (DuplicateAsSubMaterialAtIndex(pMaterial, pNewMaterial, subMaterialIndex)) - { - ++subMaterialIndex; - } - } - } - - pNewMaterial->Update(); - const bool skipReadOnly = true; - pNewMaterial->Save(skipReadOnly, fullPath); - SetCurrentMaterial(pNewMaterial); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_Delete() -{ - CMaterial* pMtl = GetCurrentMaterial(); - if (pMtl) - { - CUndo undo("Delete Material"); - QString str = QObject::tr("Delete Material %1?\r\nNote: Material file %2 will also be deleted.") - .arg(pMtl->GetName(), pMtl->GetFilename()); - if (QMessageBox::question(QApplication::activeWindow(), QObject::tr("Delete Confirmation"), str) == QMessageBox::Yes) - { - AZStd::string matName = pMtl->GetFilename().toUtf8().data(); - DeleteMaterial(pMtl); - RemoveMaterialFromDisk(matName.c_str()); - SetCurrentMaterial(0); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_AssignToSelection() -{ - CMaterial* pMtl = GetCurrentMaterial(); - if (pMtl) - { - CUndo undo("Assign Material"); - CSelectionGroup* pSel = GetIEditor()->GetSelection(); - if (pMtl->IsPureChild()) - { - const QString title = QObject::tr("Assign Submaterial"); - const QString message = QObject::tr("You can assign submaterials to objects only for preview purpose. This assignment will not be saved with the level and will not be exported to the game."); - if (QMessageBox::information(QApplication::activeWindow(), title, message, QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) - { - return; - } - } - if (!pSel->IsEmpty()) - { - for (int i = 0; i < pSel->GetCount(); i++) - { - pSel->GetObject(i)->SetMaterial(pMtl); - } - } - } - CViewport* pViewport = GetIEditor()->GetActiveView(); - if (pViewport) - { - pViewport->Drop(QPoint(-1, -1), pMtl); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_ResetSelection() -{ - CSelectionGroup* pSel = GetIEditor()->GetSelection(); - if (!pSel->IsEmpty()) - { - CUndo undo("Reset Material"); - for (int i = 0; i < pSel->GetCount(); i++) - { - pSel->GetObject(i)->SetMaterial(0); - } - } - CViewport* pViewport = GetIEditor()->GetActiveView(); - if (pViewport) - { - pViewport->Drop(QPoint(-1, -1), 0); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_SelectAssignedObjects() -{ - CMaterial* pMtl = GetCurrentMaterial(); - if (pMtl) - { - CUndo undo("Select Object(s)"); - CBaseObjectsArray objects; - GetIEditor()->GetObjectManager()->GetObjects(objects); - for (int i = 0; i < objects.size(); i++) - { - CBaseObject* pObject = objects[i]; - if (pObject->GetMaterial() == pMtl || pObject->GetRenderMaterial() == pMtl) - { - if (pObject->IsHidden() || pObject->IsFrozen()) - { - continue; - } - GetIEditor()->GetObjectManager()->SelectObject(pObject); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::Command_SelectFromObject() -{ - if (GetIEditor()->IsInPreviewMode()) - { - CViewport* pViewport = GetIEditor()->GetActiveView(); - if (CModelViewport* p = viewport_cast(pViewport)) - { - CMaterial* pMtl = p->GetMaterial(); - SetCurrentMaterial(pMtl); - } - return; - } - - CSelectionGroup* pSel = GetIEditor()->GetSelection(); - if (pSel->IsEmpty()) - { - return; - } - - for (int i = 0; i < pSel->GetCount(); i++) - { - CMaterial* pMtl = pSel->GetObject(i)->GetRenderMaterial(); - if (pMtl) - { - SetCurrentMaterial(pMtl); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::PickPreviewMaterial() -{ - XmlNodeRef data = XmlHelpers::CreateXmlNode("ExportMaterial"); - CMaterial* pMtl = GetCurrentMaterial(); - if (!pMtl) - { - return; - } - - if (pMtl->IsPureChild() && pMtl->GetParent()) - { - pMtl = pMtl->GetParent(); - } - - if (pMtl->GetFlags() & MTL_FLAG_WIRE) - { - data->setAttr("Flag_Wire", 1); - } - if (pMtl->GetFlags() & MTL_FLAG_2SIDED) - { - data->setAttr("Flag_2Sided", 1); - } - - data->setAttr("Name", pMtl->GetName().toUtf8().data()); - data->setAttr("FileName", pMtl->GetFilename().toUtf8().data()); - - XmlNodeRef node = data->newChild("Material"); - - CBaseLibraryItem::SerializeContext serCtx(node, false); - pMtl->Serialize(serCtx); - - - if (!pMtl->IsMultiSubMaterial()) - { - XmlNodeRef texturesNode = node->findChild("Textures"); - if (texturesNode) - { - for (int i = 0; i < texturesNode->getChildCount(); i++) - { - XmlNodeRef texNode = texturesNode->getChild(i); - QString file; - if (texNode->getAttr("File", file)) - { - texNode->setAttr("File", Path::GamePathToFullPath(file).toUtf8().data()); - } - } - } - } - else - { - XmlNodeRef childsNode = node->findChild("SubMaterials"); - if (childsNode) - { - int nSubMtls = childsNode->getChildCount(); - for (int i = 0; i < nSubMtls; i++) - { - XmlNodeRef node2 = childsNode->getChild(i); - XmlNodeRef texturesNode = node2->findChild("Textures"); - if (texturesNode) - { - for (int ii = 0; ii < texturesNode->getChildCount(); ii++) - { - XmlNodeRef texNode = texturesNode->getChild(ii); - QString file; - if (texNode->getAttr("File", file)) - { - texNode->setAttr("File", Path::GamePathToFullPath(file).toUtf8().data()); - } - } - } - } - } - } - - - m_MatSender->SendMessage(eMSM_GetSelectedMaterial, data); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SyncMaterialEditor() -{ -#if defined(AZ_PLATFORM_WINDOWS) - if (!m_MatSender) - { - return; - } - - if (!m_MatSender->GetMessage()) - { - return; - } - - if (m_MatSender->m_h.msg == eMSM_Create) - { - XmlNodeRef node = m_MatSender->m_node->findChild("Material"); - if (!node) - { - return; - } - - QString sMtlName; - QString sMaxFile; - - XmlNodeRef root = m_MatSender->m_node; - root->getAttr("Name", sMtlName); - root->getAttr("MaxFile", sMaxFile); - - int IsMulti = 0; - root->getAttr("IsMulti", IsMulti); - - int nMtlFlags = 0; - if (IsMulti) - { - nMtlFlags |= MTL_FLAG_MULTI_SUBMTL; - } - - if (root->haveAttr("Flag_Wire")) - { - nMtlFlags |= MTL_FLAG_WIRE; - } - if (root->haveAttr("Flag_2Sided")) - { - nMtlFlags |= MTL_FLAG_2SIDED; - } - - _smart_ptr pMtl = SelectNewMaterial(nMtlFlags, Path::GetPath(sMaxFile).toUtf8().data()); - - if (!pMtl) - { - return; - } - - if (!IsMulti) - { - node->delAttr("Shader"); // Remove shader attribute. - XmlNodeRef texturesNode = node->findChild("Textures"); - if (texturesNode) - { - for (int i = 0; i < texturesNode->getChildCount(); i++) - { - XmlNodeRef texNode = texturesNode->getChild(i); - QString file; - if (texNode->getAttr("File", file)) - { - //make path relative to the project specific game folder - QString newfile = Path::MakeGamePath(file); - if (!newfile.isEmpty()) - { - file = newfile; - } - texNode->setAttr("File", file.toUtf8().data()); - } - } - } - } - else - { - XmlNodeRef childsNode = node->findChild("SubMaterials"); - if (childsNode) - { - int nSubMtls = childsNode->getChildCount(); - for (int i = 0; i < nSubMtls; i++) - { - XmlNodeRef node2 = childsNode->getChild(i); - node2->delAttr("Shader"); // Remove shader attribute. - XmlNodeRef texturesNode = node2->findChild("Textures"); - if (texturesNode) - { - for (int ii = 0; ii < texturesNode->getChildCount(); ii++) - { - XmlNodeRef texNode = texturesNode->getChild(ii); - QString file; - if (texNode->getAttr("File", file)) - { - //make path relative to the project specific game folder - QString newfile = Path::MakeGamePath(file); - if (!newfile.isEmpty()) - { - file = newfile; - } - texNode->setAttr("File", file.toUtf8().data()); - } - } - } - } - } - } - - CBaseLibraryItem::SerializeContext ctx(node, true); - ctx.bUndo = true; - pMtl->Serialize(ctx); - - pMtl->Update(); - - SetCurrentMaterial(0); - SetCurrentMaterial(pMtl); - } - - if (m_MatSender->m_h.msg == eMSM_GetSelectedMaterial) - { - PickPreviewMaterial(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::InitMatSender() -{ - //MatSend(true); - m_MatSender->Create(); - QWidget* mainWindow = MainWindow::instance(); - m_MatSender->SetupWindows(mainWindow, mainWindow); - XmlNodeRef node = XmlHelpers::CreateXmlNode("Temp"); - m_MatSender->SendMessage(eMSM_Init, node); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::GotoMaterial([[maybe_unused]] CMaterial* pMaterial) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::GotoMaterial([[maybe_unused]] _smart_ptr pMtl) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetHighlightedMaterial(CMaterial* pMtl) -{ - if (m_pHighlightMaterial) - { - RemoveFromHighlighting(m_pHighlightMaterial, eHighlight_Pick); - } - - m_pHighlightMaterial = pMtl; - if (m_pHighlightMaterial) - { - AddForHighlighting(m_pHighlightMaterial); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::HighlightedMaterialChanged(CMaterial* pMtl) -{ - if (!pMtl) - { - return; - } - - RemoveFromHighlighting(pMtl, eHighlight_All); - AddForHighlighting(pMtl); -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::SetHighlightMask(int highlightMask) -{ - if (m_highlightMask != highlightMask) - { - m_highlightMask = highlightMask; - - UpdateHighlightedMaterials(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMaterialManager::GatherResources(_smart_ptr pMaterial, CUsedResources& resources) -{ - if (!pMaterial) - { - return; - } - - int nSubMtlCount = pMaterial->GetSubMtlCount(); - if (nSubMtlCount > 0) - { - for (int i = 0; i < nSubMtlCount; i++) - { - GatherResources(pMaterial->GetSubMtl(i), resources); - } - } - else - { - SShaderItem& shItem = pMaterial->GetShaderItem(); - if (shItem.m_pShaderResources) - { - SInputShaderResources res; - shItem.m_pShaderResources->ConvertToInputResource(&res); - - for (auto& iter : res.m_TexturesResourcesMap ) - { - SEfResTexture* pTexture = &(iter.second); - if (!pTexture->m_Name.empty()) - { - resources.Add(pTexture->m_Name.c_str()); - } - } - gEnv->pRenderer->EF_ReleaseInputShaderResource(&res); - } - } -} - -/////////////////////////////////////////////////////////////////////////// -void CMaterialManager::GetHighlightColor(ColorF* color, float* intensity, int flags) -{ - MAKE_SURE(m_pHighlighter, return ); - m_pHighlighter->GetHighlightColor(color, intensity, flags); -} - -/////////////////////////////////////////////////////////////////////////// -// This will be called when the editor welcome screen is displayed. -// At this point the editor is ready for UI events, which means we can -// process .dccmtl paths and display error to the user if necessary -bool CMaterialManager::SkipEditorStartupUI() -{ - // Editor started - m_bEditorUiReady = true; - - // If we have any file paths buffered - if (m_sourceControlBuffer.size() > 0) - { - // Start queuing - QueueSourceControlTick(); - } - - // Launch thread responsible for saving cached - // .dccmtl files as source .mtl files - StartDccMaterialSaveThread(); - - // Never want to skip Startup UI - return false; -} - -/////////////////////////////////////////////////////////////////////////// -// Queues the function TickSourceControl() to be exectued next frame -void CMaterialManager::QueueSourceControlTick() -{ - // If TickSourceControl is not currently queued - if (!m_sourceControlFunctionQueued) - { - // Queue it - AZStd::function tickFunction = [this]() - { - TickSourceControl(); - }; - AZ::SystemTickBus::QueueFunction(tickFunction); - - // Stop further queues as TickSourceControl will queue itself - // until there are no more paths in the buffer to process - m_sourceControlFunctionQueued = true; - } -} - -/////////////////////////////////////////////////////////////////////////// -// Takes a single path from m_sourceControlBuffer and passes it to -// DccMaterialSourceControlCheck(). Then if there are more paths -// remaining in the buffer, it will queue itself for execution next -// frame. The reason for doing only one material every tick is to avoid -// flooding source control with too many requests and stalling the editor -void CMaterialManager::TickSourceControl() -{ - m_sourceControlFunctionQueued = false; - AZStd::string filePath; - bool moreRemaining = false; - - { - AZStd::lock_guard lock(m_sourceControlBufferMutex); - - if (m_sourceControlBuffer.size() < 1) - { - return; - } - - filePath = m_sourceControlBuffer.back(); - m_sourceControlBuffer.pop_back(); - moreRemaining = !m_sourceControlBuffer.empty(); - } - - // Process it - DccMaterialSourceControlCheck(filePath); - - // If there are more paths to check - if (moreRemaining) - { - // Queue again - QueueSourceControlTick(); - } -} - -/////////////////////////////////////////////////////////////////////////// -// Launches new thread running the DccMaterialSaveThreadFunc() function -void CMaterialManager::StartDccMaterialSaveThread() -{ - AZStd::thread_desc threadDesc; - threadDesc.m_name = "Dcc Material Save Thread"; - - m_dccMaterialSaveThread = AZStd::thread( - [this]() - { - DccMaterialSaveThreadFunc(); - }, - &threadDesc); -} - -/////////////////////////////////////////////////////////////////////////// -// Will save all the .dccmtl file paths in the buffer to source .mtl -// Runs on a separate thread so as not to stall the main thread -void CMaterialManager::DccMaterialSaveThreadFunc() -{ - while (true) - { - m_dccMaterialSaveSemaphore.acquire(); - - // Exit condition, set to true in destructor - if (m_joinThreads) - { - return; - } - - AZStd::vector dccMaterialPaths; - - // Lock the buffer and copy file paths locally - { - AZStd::lock_guard lock(m_dccMaterialSaveMutex); - dccMaterialPaths.reserve(m_dccMaterialSaveBuffer.size()); - for (AZStd::string& fileName : m_dccMaterialSaveBuffer) - { - dccMaterialPaths.push_back(fileName); - } - m_dccMaterialSaveBuffer.clear(); - } - - // Save all the buffered .dccmtl files - for (AZStd::string& fileName : dccMaterialPaths) - { - SaveDccMaterial(fileName); - } - - // Clear local strings - dccMaterialPaths.clear(); - } -} - -/////////////////////////////////////////////////////////////////////////// -// Async source control request. If successful, the callback will add the -// file name to the buffer for processing by the Dcc Material Save Thread -void CMaterialManager::DccMaterialSourceControlCheck(const AZStd::string& relativeDccMaterialPath) -{ - AZStd::string fullSourcePath = DccMaterialToSourcePath(relativeDccMaterialPath); - - if (!DccMaterialRequiresSave(relativeDccMaterialPath, fullSourcePath)) - { - // Source .mtl update not required, early out - return; - } - - // Create callback for source control operation (see SCCommandBus::Broadcast below) - AzToolsFramework::SourceControlResponseCallback callback = - [this, relativeDccMaterialPath, fullSourcePath](bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - if (success || !info.IsReadOnly()) - { - // File needs saving, add it to the buffer for processing by the dcc material thread - - // Lock access to the buffer - AZStd::lock_guard lock(m_dccMaterialSaveMutex); - - // Add file path - m_dccMaterialSaveBuffer.push_back(relativeDccMaterialPath); - - // Notify thread there's work to do - m_dccMaterialSaveSemaphore.release(); - } - else - { - QString errorMessage = QObject::tr("Could not check out read-only file %1 in source control. Either check your source control configuration or disable source control.").arg(QString::fromUtf8(fullSourcePath.c_str())); - - // Alter error message slightly if source control is disabled - bool isSourceControlActive = false; - AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(isSourceControlActive, &AzToolsFramework::SourceControlConnectionRequestBus::Events::IsActive); - - if (!isSourceControlActive) - { - errorMessage = QObject::tr("Could not check out read-only file %1 because source control is disabled. Either enable source control or check out the file manually to make it writable.").arg(QString::fromUtf8(fullSourcePath.c_str())); - } - - // Pop open an error message box if this is the first error we encounter - if (!m_bSourceControlErrorReported) - { - // Report warning in message box - QString errorTitle = QStringLiteral("Dcc Material Error"); - QMessageBox::warning(QApplication::activeWindow(), errorTitle, errorMessage, QMessageBox::Cancel); - - // Only report source control error box to the user once, - // no need to spam them for every material - m_bSourceControlErrorReported = true; - } - - AZ_Error("Rendering", false, errorMessage.toUtf8().data()); - } - }; - - // Request edit from source control (happens asynchronously) - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullSourcePath.c_str(), true, callback); -} - -/////////////////////////////////////////////////////////////////////////// -// Handles when .dccmtl is created -void CMaterialManager::EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* assetEntry) -{ - if (assetEntry->GetEntryType() != AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Product) - { - // Ignore non-product entries - return; - } - const AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry* productAssetEntry = azrtti_cast(assetEntry); - if (productAssetEntry && productAssetEntry->GetAssetType() != m_dccMaterialAssetType) - { - // Ignore types that aren't .dccmtl - return; - } - - AddDccMaterialPath(productAssetEntry->GetRelativePath()); -} - -/////////////////////////////////////////////////////////////////////////// -// Handles when .dccmtl is edited -void CMaterialManager::OnCatalogAssetChanged(const AZ::Data::AssetId& assetId) -{ - AZ::Data::AssetInfo assetInfo; - EBUS_EVENT_RESULT(assetInfo, AZ::Data::AssetCatalogRequestBus, GetAssetInfoById, assetId); - - if (assetInfo.m_assetType != m_dccMaterialAssetType) - { - // Ignore types that aren't .dccmtl - return; - } - - AddDccMaterialPath(assetInfo.m_relativePath); -} - -/////////////////////////////////////////////////////////////////////////// -void CMaterialManager::AddDccMaterialPath(const AZStd::string relativeDccMaterialPath) -{ - if (relativeDccMaterialPath.empty()) - { - return; - } - - // Lock access to the buffer - AZStd::lock_guard lock(m_sourceControlBufferMutex); - - // Add file path - m_sourceControlBuffer.push_back(relativeDccMaterialPath); - - if (m_bEditorUiReady) - { - QueueSourceControlTick(); - } -} - -/////////////////////////////////////////////////////////////////////////// -// Given the path of a .dccmtl in cache, save it as a source .mtl -void CMaterialManager::SaveDccMaterial(const AZStd::string& relativeDccMaterialPath) -{ - // __________________________________________________ - // Load .dccmtl - - XmlNodeRef dccNode = GetISystem()->LoadXmlFromFile(relativeDccMaterialPath.c_str()); - - if (!dccNode) - { - AZ_Error("MaterialManager", false, "CMaterialManager::SaveDccMaterial: Failed to load XML node from .dccmtl file: %s", relativeDccMaterialPath.c_str()); - return; - } - - // __________________________________________________ - // Save as source .mtl file - - AZStd::string fullSourcePath = DccMaterialToSourcePath(relativeDccMaterialPath); - bool saveSuccessful = dccNode->saveToFile(fullSourcePath.c_str()); - - if (!saveSuccessful) - { - AZ_Error("MaterialManager", false, "CMaterialManager::SaveDccMaterial: Failed to save source .mtl from .dccmtl file: %s", relativeDccMaterialPath.c_str()); - } -} - -/////////////////////////////////////////////////////////////////////////// -// Compares the hash values from .dccmtl and source .mtl to determine if -// .dccmtl has changed and needs to be saved. -bool CMaterialManager::DccMaterialRequiresSave(const AZStd::string& relativeDccMaterialPath, const AZStd::string& fullSourcePath) -{ - // __________________________________________________ - // Get Source Hash - - AZ::u32 sourceHash = 0; - - // Check if material is already loaded - QString unifiedName = UnifyMaterialName(QString(relativeDccMaterialPath.c_str())); - CMaterial* sourceMaterial = (CMaterial*)FindItemByName(unifiedName); - - if (sourceMaterial && !sourceMaterial->IsDummy()) - { - sourceHash = sourceMaterial->GetDccMaterialHash(); - } - else - { - XmlNodeRef sourceNode = GetISystem()->LoadXmlFromFile(fullSourcePath.c_str()); - if (sourceNode) - { - sourceNode->getAttr("DccMaterialHash", sourceHash); - } - else - { - // Couldn't find source node or material, so we need to save the dcc material as a source material - // No need to check the dcc material hash, just return true - return true; - } - } - - // __________________________________________________ - // Get DCC material Hash - - AZ::u32 dccHash = 0; - XmlNodeRef dccNode = GetISystem()->LoadXmlFromFile(relativeDccMaterialPath.c_str()); - - if (!dccNode) - { - AZ_Error("MaterialManager", false, "CMaterialManager::DccMaterialRequiresSave: Failed to load XML node from .dccmtl file: %s", relativeDccMaterialPath.c_str()); - return false; - } - - dccNode->getAttr("DccMaterialHash", dccHash); - - // __________________________________________________ - // Compare hash values - - // Only update if .dccmtl hash is different from the source hash - return (dccHash != sourceHash); -} - diff --git a/Code/Sandbox/Editor/Material/MaterialManager.h b/Code/Sandbox/Editor/Material/MaterialManager.h deleted file mode 100644 index a9dcabfa40..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialManager.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include - - -class CMaterial; -class CMaterialLibrary; -class CMaterialHighlighter; - -namespace AZ -{ - struct Uuid; -} - -namespace AzToolsFramework -{ - namespace AssetBrowser - { - struct SourceFileOpenerDetails; - typedef AZStd::vector 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 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 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 >& 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 pMaterial); - virtual void OnDeleteMaterial(_smart_ptr pMaterial); - virtual bool IsCurrentMaterial(_smart_ptr 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 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 pMaterial); - - // Gather resources from the game material. - static void GatherResources(_smart_ptr 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 m_pCurrentMaterial; - // current selected folder - QString m_currentFolder; - // List of materials selected in material browser tree. - std::vector<_smart_ptr > m_markedMaterials; - // IMaterial is needed to not let 3Dengine release selected IMaterial - _smart_ptr 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 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 m_dccMaterialSaveBuffer; - AZStd::mutex m_dccMaterialSaveMutex; - - // Material highlighting - _smart_ptr 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 diff --git a/Code/Sandbox/Editor/Material/MaterialPreviewModelView.cpp b/Code/Sandbox/Editor/Material/MaterialPreviewModelView.cpp deleted file mode 100644 index 3e1bc37c6a..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialPreviewModelView.cpp +++ /dev/null @@ -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 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; - } -} diff --git a/Code/Sandbox/Editor/Material/MaterialPreviewModelView.h b/Code/Sandbox/Editor/Material/MaterialPreviewModelView.h deleted file mode 100644 index 0df7c1767f..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialPreviewModelView.h +++ /dev/null @@ -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 material); - void OnEditorNotifyEvent(EEditorNotifyEvent event) override; - -protected: - void resizeEvent(QResizeEvent* event) override; - -private: - bool m_enableIdleUpdate; -}; diff --git a/Code/Sandbox/Editor/Material/MaterialPythonFuncs.cpp b/Code/Sandbox/Editor/Material/MaterialPythonFuncs.cpp deleted file mode 100644 index 5de75a7c39..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialPythonFuncs.cpp +++ /dev/null @@ -1,2208 +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. - -// Description : Material support for Python - -#include "EditorDefs.h" - -#include "MaterialPythonFuncs.h" - -// Editor -#include "MaterialManager.h" -#include "ShaderEnum.h" - - -namespace -{ - void PyMaterialCreate() - { - GetIEditor()->GetMaterialManager()->Command_Create(); - } - - void PyMaterialCreateMulti() - { - GetIEditor()->GetMaterialManager()->Command_CreateMulti(); - } - - void PyMaterialConvertToMulti() - { - GetIEditor()->GetMaterialManager()->Command_ConvertToMulti(); - } - - void PyMaterialDuplicateCurrent() - { - GetIEditor()->GetMaterialManager()->Command_Duplicate(); - } - - void PyMaterialMergeSelection() - { - GetIEditor()->GetMaterialManager()->Command_Merge(); - } - - void PyMaterialDeleteCurrent() - { - GetIEditor()->GetMaterialManager()->Command_Delete(); - } - - void PyMaterialAssignCurrentToSelection() - { - CUndo undo("Assign Material To Selection"); - GetIEditor()->GetMaterialManager()->Command_AssignToSelection(); - } - - void PyMaterialResetSelection() - { - GetIEditor()->GetMaterialManager()->Command_ResetSelection(); - } - - void PyMaterialSelectObjectsWithCurrent() - { - CUndo undo("Select Objects With Current Material"); - GetIEditor()->GetMaterialManager()->Command_SelectAssignedObjects(); - } - - void PyMaterialSetCurrentFromObject() - { - GetIEditor()->GetMaterialManager()->Command_SelectFromObject(); - } - - AZStd::vector PyGetSubMaterial(const char* pMaterialPath) - { - QString materialPath = pMaterialPath; - CMaterial* pMaterial = GetIEditor()->GetMaterialManager()->LoadMaterial(pMaterialPath, false); - if (!pMaterial) - { - throw std::runtime_error("Invalid multi material."); - } - - AZStd::vector result; - for (int i = 0; i < pMaterial->GetSubMaterialCount(); i++) - { - if (pMaterial->GetSubMaterial(i)) - { - result.push_back((materialPath + "\\" + pMaterial->GetSubMaterial(i)->GetName()).toUtf8().data()); - } - } - return result; - } - - CMaterial* TryLoadingMaterial(const char* pPathAndMaterialName) - { - QString varMaterialPath = pPathAndMaterialName; - std::deque splittedMaterialPath; - for (auto token : varMaterialPath.split(QRegularExpression(R"([\\/])"), Qt::SkipEmptyParts)) - { - splittedMaterialPath.push_back(token); - } - - CMaterial* pMaterial = GetIEditor()->GetMaterialManager()->LoadMaterial(varMaterialPath, false); - if (!pMaterial) - { - QString subMaterialName = splittedMaterialPath.back(); - bool isSubMaterialExist(false); - - varMaterialPath.remove((varMaterialPath.length() - subMaterialName.length() - 1), varMaterialPath.length()); - QString test = varMaterialPath; - pMaterial = GetIEditor()->GetMaterialManager()->LoadMaterial(varMaterialPath, false); - - if (!pMaterial) - { - throw std::runtime_error("Invalid multi material."); - } - - for (int i = 0; i < pMaterial->GetSubMaterialCount(); i++) - { - if (pMaterial->GetSubMaterial(i)->GetName() == subMaterialName) - { - pMaterial = pMaterial->GetSubMaterial(i); - isSubMaterialExist = true; - } - } - - if (!pMaterial || !isSubMaterialExist) - { - throw std::runtime_error((QString("\"") + subMaterialName + "\" is an invalid sub material.").toUtf8().data()); - } - } - GetIEditor()->GetMaterialManager()->SetCurrentMaterial(pMaterial); - return pMaterial; - } - - std::deque PreparePropertyPath(const char* pPathAndPropertyName) - { - QString varPathProperty = pPathAndPropertyName; - std::deque splittedPropertyPath; - for (auto token : varPathProperty.split(QRegularExpression(R"([\\/])"), Qt::SkipEmptyParts)) - { - splittedPropertyPath.push_back(token); - } - - return splittedPropertyPath; - } - - ////////////////////////////////////////////////////////////////////////// - // Converter: Enum -> CString (human readable) - ////////////////////////////////////////////////////////////////////////// - - QString TryConvertingSEFResTextureToCString(SEfResTexture* pResTexture) - { - if (pResTexture) - { - return pResTexture->m_Name.c_str(); - } - return ""; - } - - QString TryConvertingETEX_TypeToCString(const uint8& texTypeName) - { - switch (texTypeName) - { - case eTT_2D: - return "2D"; - case eTT_Cube: - return "Cube-Map"; - case eTT_NearestCube: - return "Nearest Cube-Map probe for alpha blended"; - case eTT_Auto2D: - return "Auto 2D-Map"; - case eTT_Dyn2D: - return "Dynamic 2D-Map"; - case eTT_User: - return "From User Params"; - default: - throw std::runtime_error("Invalid tex type."); - } - } - - QString TryConvertingTexFilterToCString(const int& iFilterName) - { - switch (iFilterName) - { - case FILTER_NONE: - return "Default"; - case FILTER_POINT: - return "Point"; - case FILTER_LINEAR: - return "Linear"; - case FILTER_BILINEAR: - return "Bilinear"; - case FILTER_TRILINEAR: - return "Trilinear"; - case FILTER_ANISO2X: - return "Anisotropic 2x"; - case FILTER_ANISO4X: - return "Anisotropic 4x"; - case FILTER_ANISO8X: - return "Anisotropic 8x"; - case FILTER_ANISO16X: - return "Anisotropic 16x"; - default: - throw std::runtime_error("Invalid tex filter."); - } - } - - QString TryConvertingETexGenTypeToCString(const uint8& texGenType) - { - switch (texGenType) - { - case ETG_Stream: - return "Stream"; - case ETG_World: - return "World"; - case ETG_Camera: - return "Camera"; - default: - throw std::runtime_error("Invalid tex gen type."); - } - } - - QString TryConvertingETexModRotateTypeToCString(const uint8& rotateType) - { - switch (rotateType) - { - case ETMR_NoChange: - return "No Change"; - case ETMR_Fixed: - return "Fixed Rotation"; - case ETMR_Constant: - return "Constant Rotation"; - case ETMR_Oscillated: - return "Oscillated Rotation"; - default: - throw std::runtime_error("Invalid rotate type."); - } - } - - QString TryConvertingETexModMoveTypeToCString(const uint8& oscillatorType) - { - switch (oscillatorType) - { - case ETMM_NoChange: - return "No Change"; - case ETMM_Fixed: - return "Fixed Moving"; - case ETMM_Constant: - return "Constant Moving"; - case ETMM_Jitter: - return "Jitter Moving"; - case ETMM_Pan: - return "Pan Moving"; - case ETMM_Stretch: - return "Stretch Moving"; - case ETMM_StretchRepeat: - return "Stretch-Repeat Moving"; - default: - throw std::runtime_error("Invalid oscillator type."); - } - } - - QString TryConvertingEDeformTypeToCString(const EDeformType& deformType) - { - switch (deformType) - { - case eDT_Unknown: - return "None"; - case eDT_SinWave: - return "Sin Wave"; - case eDT_SinWaveUsingVtxColor: - return "Sin Wave using vertex color"; - case eDT_Bulge: - return "Bulge"; - case eDT_Squeeze: - return "Squeeze"; - case eDT_Perlin2D: - return "Perlin 2D"; - case eDT_Perlin3D: - return "Perlin 3D"; - case eDT_FromCenter: - return "From Center"; - case eDT_Bending: - return "Bending"; - case eDT_ProcFlare: - return "Proc. Flare"; - case eDT_AutoSprite: - return "Auto sprite"; - case eDT_Beam: - return "Beam"; - case eDT_FixedOffset: - return "FixedOffset"; - default: - throw std::runtime_error("Invalid deform type."); - } - } - - QString TryConvertingEWaveFormToCString(const EWaveForm& waveForm) - { - switch (waveForm) - { - case eWF_None: - return "None"; - case eWF_Sin: - return "Sin"; - case eWF_HalfSin: - return "Half Sin"; - case eWF_Square: - return "Square"; - case eWF_Triangle: - return "Triangle"; - case eWF_SawTooth: - return "Saw Tooth"; - case eWF_InvSawTooth: - return "Inverse Saw Tooth"; - case eWF_Hill: - return "Hill"; - case eWF_InvHill: - return "Inverse Hill"; - default: - throw std::runtime_error("Invalid wave form."); - } - } - - ////////////////////////////////////////////////////////////////////////// - // Converter: CString -> Enum - ////////////////////////////////////////////////////////////////////////// - - template - // [Shader System TO DO] remove once dynamic slots assingment is in place - EEfResTextures TryConvertingCStringToEEfResTextures(const STRING& resTextureName) - { - if (resTextureName == "Diffuse") - { - return EFTT_DIFFUSE; - } - else if (resTextureName == "Specular") - { - return EFTT_SPECULAR; - } - else if (resTextureName == "Bumpmap") - { - return EFTT_NORMALS; - } - else if (resTextureName == "Heightmap") - { - return EFTT_HEIGHT; - } - else if (resTextureName == "Environment") - { - return EFTT_ENV; - } - else if (resTextureName == "Detail") - { - return EFTT_DETAIL_OVERLAY; - } - else if (resTextureName == "Opacity") - { - return EFTT_OPACITY; - } - else if (resTextureName == "Decal") - { - return EFTT_DECAL_OVERLAY; - } - else if (resTextureName == "SubSurface") - { - return EFTT_SUBSURFACE; - } - else if (resTextureName == "Custom") - { - return EFTT_CUSTOM; - } - else if (resTextureName == "[1] Custom") - { - return EFTT_DIFFUSE; - } - else if (resTextureName == "Emittance") - { - return EFTT_EMITTANCE; - } - else if (resTextureName == "Occlusion") - { - return EFTT_OCCLUSION; - } - else if (resTextureName == "Specular2") - { - return EFTT_SPECULAR_2; - } - throw std::runtime_error("Invalid texture name."); - } - - template - ETEX_Type TryConvertingCStringToETEX_Type(const STRING& texTypeName) - { - if (texTypeName == "2D") - { - return eTT_2D; - } - else if (texTypeName == "Cube-Map") - { - return eTT_Cube; - } - else if (texTypeName == "Nearest Cube-Map probe for alpha blended") - { - return eTT_NearestCube; - } - else if (texTypeName == "Auto 2D-Map") - { - return eTT_Auto2D; - } - else if (texTypeName == "Dynamic 2D-Map") - { - return eTT_Dyn2D; - } - else if (texTypeName == "From User Params") - { - return eTT_User; - } - throw std::runtime_error("Invalid tex type name."); - } - - template - signed char TryConvertingCStringToTexFilter(const STRING& filterName) - { - if (filterName == "Default") - { - return FILTER_NONE; - } - else if (filterName == "Point") - { - return FILTER_POINT; - } - else if (filterName == "Linear") - { - return FILTER_LINEAR; - } - else if (filterName == "Bilinear") - { - return FILTER_BILINEAR; - } - else if (filterName == "Trilinear") - { - return FILTER_TRILINEAR; - } - else if (filterName == "Anisotropic 2x") - { - return FILTER_ANISO2X; - } - else if (filterName == "Anisotropic 4x") - { - return FILTER_ANISO4X; - } - else if (filterName == "Anisotropic 8x") - { - return FILTER_ANISO8X; - } - else if (filterName == "Anisotropic 16x") - { - return FILTER_ANISO16X; - } - throw std::runtime_error("Invalid filter name."); - } - - template - ETexGenType TryConvertingCStringToETexGenType(const STRING& texGenType) - { - if (texGenType == "Stream") - { - return ETG_Stream; - } - else if (texGenType == "World") - { - return ETG_World; - } - else if (texGenType == "Camera") - { - return ETG_Camera; - } - throw std::runtime_error("Invalid tex gen type name."); - } - - template - ETexModRotateType TryConvertingCStringToETexModRotateType(const STRING& rotateType) - { - if (rotateType == "No Change") - { - return ETMR_NoChange; - } - else if (rotateType == "Fixed Rotation") - { - return ETMR_Fixed; - } - else if (rotateType == "Constant Rotation") - { - return ETMR_Constant; - } - else if (rotateType == "Oscillated Rotation") - { - return ETMR_Oscillated; - } - throw std::runtime_error("Invalid rotate type name."); - } - - template - ETexModMoveType TryConvertingCStringToETexModMoveType(const STRING& oscillatorType) - { - if (oscillatorType == "No Change") - { - return ETMM_NoChange; - } - else if (oscillatorType == "Fixed Moving") - { - return ETMM_Fixed; - } - else if (oscillatorType == "Constant Moving") - { - return ETMM_Constant; - } - else if (oscillatorType == "Jitter Moving") - { - return ETMM_Jitter; - } - else if (oscillatorType == "Pan Moving") - { - return ETMM_Pan; - } - else if (oscillatorType == "Stretch Moving") - { - return ETMM_Stretch; - } - else if (oscillatorType == "Stretch-Repeat Moving") - { - return ETMM_StretchRepeat; - } - throw std::runtime_error("Invalid oscillator type."); - } - - template - EDeformType TryConvertingCStringToEDeformType(const STRING& deformType) - { - if (deformType == "None") - { - return eDT_Unknown; - } - else if (deformType == "Sin Wave") - { - return eDT_SinWave; - } - else if (deformType == "Sin Wave using vertex color") - { - return eDT_SinWaveUsingVtxColor; - } - else if (deformType == "Bulge") - { - return eDT_Bulge; - } - else if (deformType == "Squeeze") - { - return eDT_Squeeze; - } - else if (deformType == "Perlin 2D") - { - return eDT_Perlin2D; - } - else if (deformType == "Perlin 3D") - { - return eDT_Perlin3D; - } - else if (deformType == "From Center") - { - return eDT_FromCenter; - } - else if (deformType == "Bending") - { - return eDT_Bending; - } - else if (deformType == "Proc. Flare") - { - return eDT_ProcFlare; - } - else if (deformType == "Auto sprite") - { - return eDT_AutoSprite; - } - else if (deformType == "Beam") - { - return eDT_Beam; - } - else if (deformType == "FixedOffset") - { - return eDT_FixedOffset; - } - throw std::runtime_error("Invalid deform type."); - } - - template - EWaveForm TryConvertingCStringToEWaveForm(const STRING& waveForm) - { - if (waveForm == "None") - { - return eWF_None; - } - else if (waveForm == "Sin") - { - return eWF_Sin; - } - else if (waveForm == "Half Sin") - { - return eWF_HalfSin; - } - else if (waveForm == "Square") - { - return eWF_Square; - } - else if (waveForm == "Triangle") - { - return eWF_Triangle; - } - else if (waveForm == "Saw Tooth") - { - return eWF_SawTooth; - } - else if (waveForm == "Inverse Saw Tooth") - { - return eWF_InvSawTooth; - } - else if (waveForm == "Hill") - { - return eWF_Hill; - } - else if (waveForm == "Inverse Hill") - { - return eWF_InvHill; - } - throw std::runtime_error("Invalid wave form."); - } - - ////////////////////////////////////////////////////////////////////////// - // Script parser - ////////////////////////////////////////////////////////////////////////// - - QString ParseUINameFromPublicParamsScript(const char* sUIScript) - { - 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); - } - - if (_stricmp(element[1], "UIName") == 0) - { - return element[2].c_str(); - } - itemToken = uiscript.Tokenize(";", p1); - } - return ""; - } - - std::map ParseValidRangeFromPublicParamsScript(const char* sUIScript) - { - string uiscript = sUIScript; - std::map result; - bool isUIMinExist(false); - bool isUIMaxExist(false); - 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); - } - - if (_stricmp(element[1], "UIMin") == 0) - { - result["UIMin"] = atof(element[2]); - isUIMinExist = true; - } - if (_stricmp(element[1], "UIMax") == 0) - { - result["UIMax"] = atof(element[2]); - isUIMaxExist = true; - } - itemToken = uiscript.Tokenize(";", p1); - } - if (!isUIMinExist || !isUIMaxExist) - { - throw std::runtime_error("Invalid range for shader param."); - } - return result; - } - - ////////////////////////////////////////////////////////////////////////// - // Set Flags - ////////////////////////////////////////////////////////////////////////// - - void SetMaterialFlag(CMaterial* pMaterial, const EMaterialFlags& eFlag, const bool& bFlag) - { - if (pMaterial->GetFlags() & eFlag && bFlag == false) - { - pMaterial->SetFlags(pMaterial->GetFlags() - eFlag); - } - else if (!(pMaterial->GetFlags() & eFlag) && bFlag == true) - { - pMaterial->SetFlags(pMaterial->GetFlags() | eFlag); - } - } - - void SetPropagationFlag(CMaterial* pMaterial, const eMTL_PROPAGATION& eFlag, const bool& bFlag) - { - if (pMaterial->GetPropagationFlags() & eFlag && bFlag == false) - { - pMaterial->SetPropagationFlags(pMaterial->GetPropagationFlags() - eFlag); - } - else if (!(pMaterial->GetPropagationFlags() & eFlag) && bFlag == true) - { - pMaterial->SetPropagationFlags(pMaterial->GetPropagationFlags() | eFlag); - } - } - - ////////////////////////////////////////////////////////////////////////// - template - bool IsAnyValidRange(const AZStd::any& value, const T& low, const T& high, const QString& invalidTypeMessage, const QString& invalidValueMessage) - { - static_assert(AZStd::is_arithmetic::value, "This function only works with numbers."); - - if (!value.is()) - { - throw std::runtime_error(invalidTypeMessage.toUtf8().data()); - } - - T valueData; - AZStd::any_numeric_cast(&value, valueData); - if (valueData < low || valueData > high) - { - throw std::runtime_error(invalidValueMessage.toUtf8().data()); - } - return true; - } - - template <> - bool IsAnyValidRange(const AZStd::any& value, const AZ::Color& low, const AZ::Color& high, const QString& invalidTypeMessage, const QString& invalidValueMessage) - { - if (!value.is()) - { - throw std::runtime_error(invalidTypeMessage.toUtf8().data()); - } - - const AZ::Color* valueData = AZStd::any_cast(&value); - if (!valueData) - { - throw std::runtime_error(invalidValueMessage.toUtf8().data()); - } - - if (valueData->IsLessThan(low) || valueData->IsGreaterThan(high)) - { - throw std::runtime_error(invalidValueMessage.toUtf8().data()); - } - return true; - } - - bool ValidateProperty(CMaterial* pMaterial, const std::deque& splittedPropertyPathParam, const AZStd::any& value) - { - std::deque splittedPropertyPath = splittedPropertyPathParam; - std::deque splittedPropertyPathSubCategory = splittedPropertyPathParam; - QString categoryName = splittedPropertyPath.front(); - QString subCategoryName = ""; - QString subSubCategoryName = ""; - QString currentPath = ""; - QString propertyName = splittedPropertyPath.back(); - - QString errorMsgInvalidValue = QString("Invalid value for property \"") + propertyName + "\""; - QString errorMsgInvalidDataType = QString("Invalid data type for property \"") + propertyName + "\""; - QString errorMsgInvalidPropertyPath = QString("Invalid property path"); - - const int iMinColorValue = 0; - const int iMaxColorValue = 255; - - if (splittedPropertyPathSubCategory.size() == 3) - { - splittedPropertyPathSubCategory.pop_back(); - subCategoryName = splittedPropertyPathSubCategory.back(); - currentPath = QString("") + categoryName + "/" + subCategoryName; - - if ( - subCategoryName != "TexType" && - subCategoryName != "Filter" && - subCategoryName != "IsProjectedTexGen" && - subCategoryName != "TexGenType" && - subCategoryName != "Wave X" && - subCategoryName != "Wave Y" && - subCategoryName != "Wave Z" && - subCategoryName != "Wave W" && - subCategoryName != "Shader1" && - subCategoryName != "Shader2" && - subCategoryName != "Shader3" && - subCategoryName != "Tiling" && - subCategoryName != "Rotator" && - subCategoryName != "Oscillator" && - subCategoryName != "Diffuse" && - subCategoryName != "Specular" && - subCategoryName != "Bumpmap" && - subCategoryName != "Heightmap" && - subCategoryName != "Environment" && - subCategoryName != "Detail" && - subCategoryName != "Opacity" && - subCategoryName != "Decal" && - subCategoryName != "SubSurface" && - subCategoryName != "Custom" && - subCategoryName != "[1] Custom" - ) - { - throw std::runtime_error((errorMsgInvalidPropertyPath + " (" + currentPath + ")").toUtf8().data()); - } - } - else if (splittedPropertyPathSubCategory.size() == 4) - { - splittedPropertyPathSubCategory.pop_back(); - subCategoryName = splittedPropertyPathSubCategory.back(); - splittedPropertyPathSubCategory.pop_back(); - subSubCategoryName = splittedPropertyPathSubCategory.back(); - currentPath = categoryName + "/" + subSubCategoryName + "/" + subCategoryName; - - if ( - subSubCategoryName != "Diffuse" && - subSubCategoryName != "Specular" && - subSubCategoryName != "Bumpmap" && - subSubCategoryName != "Heightmap" && - subSubCategoryName != "Environment" && - subSubCategoryName != "Detail" && - subSubCategoryName != "Opacity" && - subSubCategoryName != "Decal" && - subSubCategoryName != "SubSurface" && - subSubCategoryName != "Custom" && - subSubCategoryName != "[1] Custom" - ) - { - throw std::runtime_error((errorMsgInvalidPropertyPath + " (" + currentPath + ")").toUtf8().data()); - } - else if (subCategoryName != "Tiling" && subCategoryName != "Rotator" && subCategoryName != "Oscillator") - { - throw std::runtime_error((errorMsgInvalidPropertyPath + " (" + currentPath + ")").toUtf8().data()); - } - } - else - { - currentPath = categoryName; - } - - if ( - categoryName == "Material Settings" || - categoryName == "Opacity Settings" || - categoryName == "Lighting Settings" || - categoryName == "Advanced" || - categoryName == "Texture Maps" || - categoryName == "Vertex Deformation" || - categoryName == "Layer Presets") - { - if (propertyName == "Opacity" || propertyName == "AlphaTest" || propertyName == "Glow Amount") - { - // int: 0 < x < 100 - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - - AZ::s64 valueData; - AZStd::any_numeric_cast(&value, valueData); - if (valueData < 0 || valueData > 100) - { - throw std::runtime_error(errorMsgInvalidValue.toUtf8().data()); - } - return true; - } - else if (propertyName == "Smoothness" || propertyName == "Glossiness") - { - // int: 0 < x < 255 - return IsAnyValidRange(value, 0, 255, errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if (propertyName == "Specular Level") - { - // float: 0.0 < x < 4.0 - return IsAnyValidRange(value, 0.0, 4.0, errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if ( - propertyName == "TileU" || - propertyName == "TileV" || - propertyName == "OffsetU" || - propertyName == "OffsetV" || - propertyName == "RotateU" || - propertyName == "RotateV" || - propertyName == "RotateW" || - propertyName == "Rate" || - propertyName == "Phase" || - propertyName == "Amplitude" || - propertyName == "CenterU" || - propertyName == "CenterV" || - propertyName == "RateU" || - propertyName == "RateV" || - propertyName == "PhaseU" || - propertyName == "PhaseV" || - propertyName == "AmplitudeU" || - propertyName == "AmplitudeV" || - propertyName == "Wave Length X" || - propertyName == "Wave Length Y" || - propertyName == "Wave Length Z" || - propertyName == "Wave Length W" || - propertyName == "Level" || - propertyName == "Amplitude" || - propertyName == "Phase" || - propertyName == "Frequency") - { - // float: 0.0 < x < 100.0 - return IsAnyValidRange(value, 0.0, 100.0, errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if (propertyName == "Voxel Coverage") - { - // float: 0.0 < x < 1.0 - return IsAnyValidRange(value, 0.0, 1.0, errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if (propertyName == "Emissive Intensity") - { - // float: 0.0 < x < 200.0 - return IsAnyValidRange(value, 0.0, 200.0, errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if (propertyName == "Diffuse Color" || propertyName == "Specular Color" || propertyName == "Emissive Color") - { - // intVector(RGB): 0 < x < 255 - return IsAnyValidRange(value, AZ::Color::CreateZero(), AZ::Color::CreateOne(), errorMsgInvalidDataType, errorMsgInvalidValue); - } - else if ( - propertyName == "Link to Material" || - propertyName == "Surface Type" || - propertyName == "Diffuse" || - propertyName == "Specular" || - propertyName == "Bumpmap" || - propertyName == "Heightmap" || - propertyName == "Environment" || - propertyName == "Detail" || - propertyName == "Opacity" || - propertyName == "Decal" || - propertyName == "SubSurface" || - propertyName == "Custom" || - propertyName == "[1] Custom" || - propertyName == "TexType" || - propertyName == "Filter" || - propertyName == "TexGenType" || - propertyName == "Type" || - propertyName == "TypeU" || - propertyName == "TypeV") - { - // string - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - return true; - } - else if ( - propertyName == "Additive" || - propertyName == "Allow layer activation" || - propertyName == "2 Sided" || - propertyName == "No Shadow" || - propertyName == "Use Scattering" || - propertyName == "Hide After Breaking" || - propertyName == "Fog Volume Shading Quality High" || - propertyName == "Blend Terrain Color" || - propertyName == "Propagate Material Settings" || - propertyName == "Propagate Opacity Settings" || - propertyName == "Propagate Lighting Settings" || - propertyName == "Propagate Advanced Settings" || - propertyName == "Propagate Texture Maps" || - propertyName == "Propagate Shader Params" || - propertyName == "Propagate Shader Generation" || - propertyName == "Propagate Vertex Deformation" || - propertyName == "Propagate Layer Presets" || - propertyName == "IsProjectedTexGen" || - propertyName == "IsTileU" || - propertyName == "IsTileV" || - propertyName == "No Draw") - { - // bool - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - return true; - } - else if (propertyName == "Shader" || propertyName == "Shader1" || propertyName == "Shader2" || propertyName == "Shader3") - { - // string && valid shader - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - - CShaderEnum* pShaderEnum = GetIEditor()->GetShaderEnum(); - if (!pShaderEnum) - { - throw std::runtime_error("Shader enumerator corrupted."); - } - pShaderEnum->EnumShaders(); - for (int i = 0; i < pShaderEnum->GetShaderCount(); i++) - { - if (pShaderEnum->GetShader(i) == AZStd::any_cast(value).data()) - { - return true; - } - } - } - else if (propertyName == "Noise Scale") - { - // FloatVec: undefined < x < undefined - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - return true; - } - } - else if (categoryName == "Shader Params") - { - auto& shaderParams = pMaterial->GetShaderResources().m_ShaderParams; - for (int i = 0; i < shaderParams.size(); i++) - { - if (propertyName == ParseUINameFromPublicParamsScript(shaderParams[i].m_Script.c_str())) - { - if (shaderParams[i].m_Type == eType_FLOAT) - { - // float: valid range (from script) - float floatValue; - if (!AZStd::any_numeric_cast(&value, floatValue)) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - std::map range = ParseValidRangeFromPublicParamsScript(shaderParams[i].m_Script.c_str()); - if (floatValue < range["UIMin"] || floatValue > range["UIMax"]) - { - QString errorMsg; - errorMsg = QStringLiteral("Invalid value for shader param \"%1\" (min: %2, max: %3)").arg(propertyName).arg(range["UIMin"]).arg(range["UIMax"]); - throw std::runtime_error(errorMsg.toUtf8().data()); - } - return true; - } - else if (shaderParams[i].m_Type == eType_FCOLOR) - { - return IsAnyValidRange(value, AZ::Color::CreateZero(), AZ::Color::CreateOne(), errorMsgInvalidDataType, errorMsgInvalidValue); - } - } - } - } - else if (categoryName == "Shader Generation Params") - { - for (int i = 0; i < pMaterial->GetShaderGenParamsVars()->GetNumVariables(); i++) - { - if (propertyName == pMaterial->GetShaderGenParamsVars()->GetVariable(i)->GetHumanName()) - { - if (!value.is()) - { - throw std::runtime_error(errorMsgInvalidDataType.toUtf8().data()); - } - return true; - } - } - } - else - { - throw std::runtime_error((errorMsgInvalidPropertyPath + " (" + currentPath + ")").toUtf8().data()); - } - return false; - } - - ////////////////////////////////////////////////////////////////////////// - template - T PyFetchNumericType(const AZStd::any& value) - { - T numericValue; - AZStd::any_numeric_cast(&value, numericValue); - return numericValue; - } - - AZStd::any PyGetProperty(const char* pPathAndMaterialName, const char* pPathAndPropertyName) - { - CMaterial* pMaterial = TryLoadingMaterial(pPathAndMaterialName); - std::deque splittedPropertyPath = PreparePropertyPath(pPathAndPropertyName); - std::deque splittedPropertyPathCategory = splittedPropertyPath; - QString categoryName = splittedPropertyPath.front(); - QString subCategoryName = "None"; - QString subSubCategoryName = "None"; - QString propertyName = splittedPropertyPath.back(); - QString errorMsgInvalidPropertyPath = "Invalid property path."; - - if (splittedPropertyPathCategory.size() == 3) - { - splittedPropertyPathCategory.pop_back(); - subCategoryName = splittedPropertyPathCategory.back(); - } - else if (splittedPropertyPathCategory.size() == 4) - { - splittedPropertyPathCategory.pop_back(); - subCategoryName = splittedPropertyPathCategory.back(); - splittedPropertyPathCategory.pop_back(); - subSubCategoryName = splittedPropertyPathCategory.back(); - } - - // ########## Material Settings ########## - if (categoryName == "Material Settings") - { - if (propertyName == "Shader") - { - return AZStd::make_any(pMaterial->GetShaderName().toUtf8().data()); - } - else if (propertyName == "Surface Type") - { - QString stringValue = pMaterial->GetSurfaceTypeName(); - if (stringValue.startsWith("mat_")) - { - stringValue.remove(0, 4); - } - return AZStd::make_any(stringValue.toLatin1().data()); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid material setting.").toUtf8().data()); - } - } - // ########## Opacity Settings ########## - else if (categoryName == "Opacity Settings") - { - if (propertyName == "Opacity") - { - AZ::s64 intValue = aznumeric_cast(pMaterial->GetShaderResources().m_LMaterial.m_Opacity * 100.0f); - return AZStd::make_any(intValue); - } - else if (propertyName == "AlphaTest") - { - AZ::s64 intValue = aznumeric_cast(pMaterial->GetShaderResources().m_AlphaRef * 100.0f); - return AZStd::make_any(intValue); - } - else if (propertyName == "Additive") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_ADDITIVE); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid opacity setting.").toUtf8().data()); - } - } - // ########## Lighting Settings ########## - else if (categoryName == "Lighting Settings") - { - if (propertyName == "Diffuse Color") - { - QColor col = ColorLinearToGamma(ColorF( - pMaterial->GetShaderResources().m_LMaterial.m_Diffuse.r, - pMaterial->GetShaderResources().m_LMaterial.m_Diffuse.g, - pMaterial->GetShaderResources().m_LMaterial.m_Diffuse.b)); - return AZStd::make_any(col.red(), col.green(), col.blue(), 1.0f); - } - else if (propertyName == "Specular Color") - { - QColor col = ColorLinearToGamma(ColorF( - pMaterial->GetShaderResources().m_LMaterial.m_Specular.r / pMaterial->GetShaderResources().m_LMaterial.m_Specular.a, - pMaterial->GetShaderResources().m_LMaterial.m_Specular.g / pMaterial->GetShaderResources().m_LMaterial.m_Specular.a, - pMaterial->GetShaderResources().m_LMaterial.m_Specular.b / pMaterial->GetShaderResources().m_LMaterial.m_Specular.a)); - return AZStd::make_any(col.red(), col.green(), col.blue(), 1.0f); - } - else if (propertyName == "Glossiness") - { - return AZStd::make_any(pMaterial->GetShaderResources().m_LMaterial.m_Smoothness); - } - else if (propertyName == "Specular Level") - { - return AZStd::make_any(pMaterial->GetShaderResources().m_LMaterial.m_Specular.a); - } - else if (propertyName == "Emissive Color") - { - QColor col = ColorLinearToGamma(ColorF( - pMaterial->GetShaderResources().m_LMaterial.m_Emittance.r, - pMaterial->GetShaderResources().m_LMaterial.m_Emittance.g, - pMaterial->GetShaderResources().m_LMaterial.m_Emittance.b)); - return AZStd::make_any(col.red(), col.green(), col.blue(), 1.0f); - } - else if (propertyName == "Emissive Intensity") - { - return AZStd::make_any(pMaterial->GetShaderResources().m_LMaterial.m_Emittance.a); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid lighting setting.").toUtf8().data()); - } - } - // ########## Advanced ########## - else if (categoryName == "Advanced") - { - if (propertyName == "Allow layer activation") - { - return AZStd::make_any(pMaterial->LayerActivationAllowed()); - } - else if (propertyName == "2 Sided") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_2SIDED); - } - else if (propertyName == "No Shadow") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_NOSHADOW); - } - else if (propertyName == "Use Scattering") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_SCATTER); - } - else if (propertyName == "Hide After Breaking") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_HIDEONBREAK); - } - else if (propertyName == "Fog Volume Shading Quality High") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_FOG_VOLUME_SHADING_QUALITY_HIGH); - } - else if (propertyName == "Blend Terrain Color") - { - return AZStd::make_any(pMaterial->GetFlags() & MTL_FLAG_BLEND_TERRAIN); - } - else if (propertyName == "Voxel Coverage") - { - return AZStd::make_any(aznumeric_cast(pMaterial->GetShaderResources().m_VoxelCoverage) / 255.0f); - } - else if (propertyName == "Link to Material") - { - return AZStd::make_any(pMaterial->GetMatInfo()->GetMaterialLinkName()); - } - else if (propertyName == "Propagate Material Settings") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_MATERIAL_SETTINGS); - } - else if (propertyName == "Propagate Opacity Settings") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_OPACITY); - } - else if (propertyName == "Propagate Lighting Settings") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_LIGHTING); - } - else if (propertyName == "Propagate Advanced Settings") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_ADVANCED); - } - else if (propertyName == "Propagate Texture Maps") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_TEXTURES); - } - else if (propertyName == "Propagate Shader Params") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_SHADER_PARAMS); - } - else if (propertyName == "Propagate Shader Generation") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_SHADER_GEN); - } - else if (propertyName == "Propagate Vertex Deformation") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_VERTEX_DEF); - } - else if (propertyName == "Propagate Layer Presets") - { - return AZStd::make_any(pMaterial->GetPropagationFlags() & MTL_PROPAGATE_LAYER_PRESETS); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid advanced setting.").toUtf8().data()); - } - } - // ########## Texture Maps ########## - else if (categoryName == "Texture Maps") - { - SInputShaderResources& shaderResources = pMaterial->GetShaderResources(); - // ########## Texture Maps / [name] ########## - if (splittedPropertyPath.size() == 2) - { - uint16 nSlot = aznumeric_cast(TryConvertingCStringToEEfResTextures(propertyName)); - SEfResTexture* pTextureRes = shaderResources.GetTextureResource(nSlot); - if (!pTextureRes || pTextureRes->m_Name.empty()) - { - AZ_Warning("ShadersSystem", false, "PyGetProperty - Error: empty texture slot [%d] (or missing name) for material %s", - nSlot, pMaterial->GetName().toStdString().c_str()); - return AZStd::any(); - } - else - { - return AZStd::make_any(pTextureRes->m_Name); - } - } - // ########## Texture Maps / [TexType | Filter | IsProjectedTexGen | TexGenType ] ########## - else if (splittedPropertyPath.size() == 3) - { - SEfResTexture* pTextureRes = shaderResources.GetTextureResource(TryConvertingCStringToEEfResTextures(subCategoryName)); - if (pTextureRes) - { - if (propertyName == "TexType") - { - return AZStd::make_any(TryConvertingETEX_TypeToCString(pTextureRes->m_Sampler.m_eTexType).toLatin1().data()); - } - else if (propertyName == "Filter") - { - return AZStd::make_any(TryConvertingTexFilterToCString(pTextureRes->m_Filter).toLatin1().data()); - } - else if (propertyName == "IsProjectedTexGen") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_bTexGenProjected); - } - else if (propertyName == "TexGenType") - { - return AZStd::make_any(TryConvertingETexGenTypeToCString(pTextureRes->AddModificator()->m_eTGType).toLatin1().data()); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - else - { - AZ_Warning("ShadersSystem", false, "PyGetProperty - Error: empty 'subCategoryName' texture slot [%d] for material %s", - aznumeric_cast(TryConvertingCStringToEEfResTextures(subCategoryName)), - pMaterial->GetName().toStdString().c_str()); - } - } - // ########## Texture Maps / [Tiling | Rotator | Oscillator] ########## - else if (splittedPropertyPath.size() == 4) - { - SEfResTexture* pTextureRes = shaderResources.GetTextureResource(TryConvertingCStringToEEfResTextures(subSubCategoryName)); - if (pTextureRes) - { - if (subCategoryName == "Tiling") - { - if (propertyName == "IsTileU") - { - return AZStd::make_any(pTextureRes->m_bUTile); - } - else if (propertyName == "IsTileV") - { - return AZStd::make_any(pTextureRes->m_bVTile); - } - else if (propertyName == "TileU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Tiling[0]); - } - else if (propertyName == "TileV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Tiling[1]); - } - else if (propertyName == "OffsetU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Offs[0]); - } - else if (propertyName == "OffsetV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Offs[1]); - } - else if (propertyName == "RotateU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Rot[0]); - } - else if (propertyName == "RotateV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Rot[1]); - } - else if (propertyName == "RotateW") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_Rot[2]); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - else if (subCategoryName == "Rotator") - { - if (propertyName == "Type") - { - return AZStd::make_any(TryConvertingETexModRotateTypeToCString(pTextureRes->AddModificator()->m_eRotType).toLatin1().data()); - } - else if (propertyName == "Rate") - { - return AZStd::make_any(Word2Degr(pTextureRes->AddModificator()->m_RotOscRate[2])); - } - else if (propertyName == "Phase") - { - return AZStd::make_any(Word2Degr(pTextureRes->AddModificator()->m_RotOscPhase[2])); - } - else if (propertyName == "Amplitude") - { - return AZStd::make_any(Word2Degr(pTextureRes->AddModificator()->m_RotOscAmplitude[2])); - } - else if (propertyName == "CenterU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_RotOscCenter[0]); - } - else if (propertyName == "CenterV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_RotOscCenter[1]); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - else if (subCategoryName == "Oscillator") - { - if (propertyName == "TypeU") - { - return AZStd::make_any(TryConvertingETexModMoveTypeToCString(pTextureRes->AddModificator()->m_eMoveType[0]).toLatin1().data()); - } - else if (propertyName == "TypeV") - { - return AZStd::make_any(TryConvertingETexModMoveTypeToCString(pTextureRes->AddModificator()->m_eMoveType[1]).toLatin1().data()); - } - else if (propertyName == "RateU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscRate[0]); - - } - else if (propertyName == "RateV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscRate[1]); - } - else if (propertyName == "PhaseU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscPhase[0]); - } - else if (propertyName == "PhaseV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscPhase[1]); - } - else if (propertyName == "AmplitudeU") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscAmplitude[0]); - } - else if (propertyName == "AmplitudeV") - { - return AZStd::make_any(pTextureRes->AddModificator()->m_OscAmplitude[1]); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - else - { - throw std::runtime_error((QString("\"") + subCategoryName + "\" is an invalid sub category.").toUtf8().data()); - } - } - else - { - AZ_Warning("ShadersSystem", false, "PyGetProperty - Error: empty 'subSubCategoryName' texture slot [%d] for material %s", - aznumeric_cast(TryConvertingCStringToEEfResTextures(subSubCategoryName)), - pMaterial->GetName().toStdString().c_str()); - } - } - else - { - throw std::runtime_error(errorMsgInvalidPropertyPath.toUtf8().data()); - } - } - // ########## Shader Params ########## - else if (categoryName == "Shader Params") - { - auto& shaderParams = pMaterial->GetShaderResources().m_ShaderParams; - - for (int i = 0; i < shaderParams.size(); i++) - { - if (propertyName == ParseUINameFromPublicParamsScript(shaderParams[i].m_Script.c_str())) - { - if (shaderParams[i].m_Type == eType_FLOAT) - { - return AZStd::make_any(shaderParams[i].m_Value.m_Float); - } - else if (shaderParams[i].m_Type == eType_FCOLOR) - { - QColor col = ColorLinearToGamma(ColorF( - shaderParams[i].m_Value.m_Vector[0], - shaderParams[i].m_Value.m_Vector[1], - shaderParams[i].m_Value.m_Vector[2])); - return AZStd::make_any(col.red(), col.green(), col.blue(), 1.0f); - } - } - } - - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid shader param.").toUtf8().data()); - } - // ########## Shader Generation Params ########## - else if (categoryName == "Shader Generation Params") - { - for (int i = 0; i < pMaterial->GetShaderGenParamsVars()->GetNumVariables(); i++) - { - if (propertyName == pMaterial->GetShaderGenParamsVars()->GetVariable(i)->GetHumanName()) - { - // get the current Boolean value for this shader variable and return so that the std::runtime_error() will not throw to indicate failure - bool boolValue = false; - pMaterial->GetShaderGenParamsVars()->GetVariable(i)->Get(boolValue); - return AZStd::make_any(boolValue); - } - } - - // not matching property was found, so throw a std::runtime_error() to indcate an error - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid shader generation param.").toUtf8().data()); - } - // ########## Vertex Deformation ########## - else if (categoryName == "Vertex Deformation") - { - // ########## Vertex Deformation / [ Type | Wave Length X | Wave Length Y | Wave Length Z | Wave Length W | Noise Scale ] ########## - if (splittedPropertyPath.size() == 2) - { - if (propertyName == "Type") - { - return AZStd::make_any(TryConvertingEDeformTypeToCString(pMaterial->GetShaderResources().m_DeformInfo.m_eType).toLatin1().data()); - } - else if (propertyName == "Wave Length X") - { - return AZStd::make_any(pMaterial->GetShaderResources().m_DeformInfo.m_fDividerX); - } - else if (propertyName == "Noise Scale") - { - return AZStd::make_any( - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[0], - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[1], - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[2]); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - // ########## Vertex Deformation / [ Wave X ] ########## - else if (splittedPropertyPath.size() == 3) - { - if (subCategoryName == "Wave X") - { - SWaveForm2 currentWaveForm; - if (subCategoryName == "Wave X") - { - currentWaveForm = pMaterial->GetShaderResources().m_DeformInfo.m_WaveX; - } - - if (propertyName == "Type") - { - return AZStd::make_any(TryConvertingEWaveFormToCString(currentWaveForm.m_eWFType).toLatin1().data()); - } - else if (propertyName == "Level") - { - return AZStd::make_any(currentWaveForm.m_Level); - } - else if (propertyName == "Amplitude") - { - return AZStd::make_any(currentWaveForm.m_Amp); - } - else if (propertyName == "Phase") - { - return AZStd::make_any(currentWaveForm.m_Phase); - } - else if (propertyName == "Frequency") - { - return AZStd::make_any(currentWaveForm.m_Freq); - } - else - { - throw std::runtime_error((QString("\"") + propertyName + "\" is an invalid property.").toUtf8().data()); - } - } - else - { - throw std::runtime_error((QString("\"") + categoryName + "\" is an invalid category.").toUtf8().data()); - } - } - else - { - throw std::runtime_error(errorMsgInvalidPropertyPath.toUtf8().data()); - } - } - // ########## Layer Presets ########## - else if (categoryName == "Layer Presets") - { - // names are "Shader1", "Shader2" and "Shader3", because all have the name "Shader" in material editor - if (splittedPropertyPath.size() == 2) - { - int shaderNumber = -1; - if (propertyName == "Shader1") - { - shaderNumber = 0; - } - else if (propertyName == "Shader2") - { - shaderNumber = 1; - } - else if (propertyName == "Shader3") - { - shaderNumber = 2; - } - else - { - throw std::runtime_error("Invalid shader."); - } - - return AZStd::make_any(pMaterial->GetMtlLayerResources()[shaderNumber].m_shaderName.toLatin1().data()); - } - else if (splittedPropertyPath.size() == 3) - { - if (propertyName == "No Draw") - { - int shaderNumber = -1; - if (subCategoryName == "Shader1") - { - shaderNumber = 0; - } - else if (subCategoryName == "Shader2") - { - shaderNumber = 1; - } - else if (subCategoryName == "Shader3") - { - shaderNumber = 2; - } - else - { - throw std::runtime_error("Invalid shader."); - } - return AZStd::make_any(pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags & MTL_LAYER_USAGE_NODRAW); - } - } - } - - throw std::runtime_error(errorMsgInvalidPropertyPath.toUtf8().data()); - return AZStd::any(); - } - - void PySetProperty(const char* pPathAndMaterialName, const char* pPathAndPropertyName, const AZStd::any& value) - { - CMaterial* pMaterial = TryLoadingMaterial(pPathAndMaterialName); - std::deque splittedPropertyPath = PreparePropertyPath(pPathAndPropertyName); - std::deque splittedPropertyPathCategory = splittedPropertyPath; - QString categoryName = splittedPropertyPath.front(); - QString subCategoryName = "None"; - QString subSubCategoryName = "None"; - QString propertyName = splittedPropertyPath.back(); - QString errorMsgInvalidPropertyPath = "Invalid property path."; - - if (!ValidateProperty(pMaterial, splittedPropertyPath, value)) - { - throw std::runtime_error("Invalid property."); - } - - QString undoMsg = "Set Material Property"; - CUndo undo(undoMsg.toUtf8().data()); - pMaterial->RecordUndo(undoMsg.toUtf8().data(), true); - - if (splittedPropertyPathCategory.size() == 3) - { - splittedPropertyPathCategory.pop_back(); - subCategoryName = splittedPropertyPathCategory.back(); - } - else if (splittedPropertyPathCategory.size() == 4) - { - splittedPropertyPathCategory.pop_back(); - subCategoryName = splittedPropertyPathCategory.back(); - splittedPropertyPathCategory.pop_back(); - subSubCategoryName = splittedPropertyPathCategory.back(); - } - - // ########## Material Settings ########## - if (categoryName == "Material Settings") - { - if (propertyName == "Shader") - { - pMaterial->SetShaderName(AZStd::any_cast(value).data()); - } - else if (propertyName == "Surface Type") - { - bool isSurfaceExist(false); - QString realSurfacename = ""; - ISurfaceTypeEnumerator* pSurfaceTypeEnum = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager()->GetEnumerator(); - if (pSurfaceTypeEnum) - { - for (ISurfaceType* pSurfaceType = pSurfaceTypeEnum->GetFirst(); pSurfaceType; pSurfaceType = pSurfaceTypeEnum->GetNext()) - { - QString surfaceName = pSurfaceType->GetName(); - realSurfacename = surfaceName; - if (surfaceName.left(4) == "mat_") - { - surfaceName.remove(0, 4); - } - if (surfaceName == AZStd::any_cast(value).data()) - { - isSurfaceExist = true; - pMaterial->SetSurfaceTypeName(realSurfacename); - } - } - - if (!isSurfaceExist) - { - throw std::runtime_error("Invalid surface type name."); - } - } - else - { - throw std::runtime_error("Surface Type Enumerator corrupted."); - } - } - } - // ########## Opacity Settings ########## - else if (categoryName == "Opacity Settings") - { - if (propertyName == "Opacity") - { - pMaterial->GetShaderResources().m_LMaterial.m_Opacity = PyFetchNumericType(value) / 100.0f; - } - else if (propertyName == "AlphaTest") - { - pMaterial->GetShaderResources().m_AlphaRef = PyFetchNumericType(value) / 100.0f; - } - else if (propertyName == "Additive") - { - SetMaterialFlag(pMaterial, MTL_FLAG_ADDITIVE, PyFetchNumericType(value)); - } - } - // ########## Lighting Settings ########## - else if (categoryName == "Lighting Settings") - { - if (propertyName == "Diffuse Color") - { - const AZ::Color* color = AZStd::any_cast(&value); - pMaterial->GetShaderResources().m_LMaterial.m_Diffuse = ColorGammaToLinear(QColor(color->GetR8(), color->GetG8(), color->GetB8())); - } - else if (propertyName == "Specular Color") - { - const AZ::Color* color = AZStd::any_cast(&value); - ColorF colorFloat = ColorGammaToLinear(QColor(color->GetR8(), color->GetG8(), color->GetB8())); - colorFloat.a = pMaterial->GetShaderResources().m_LMaterial.m_Specular.a; - colorFloat.r *= colorFloat.a; - colorFloat.g *= colorFloat.a; - colorFloat.b *= colorFloat.a; - pMaterial->GetShaderResources().m_LMaterial.m_Specular = colorFloat; - } - else if (propertyName == "Glossiness" || propertyName == "Smoothness") - { - pMaterial->GetShaderResources().m_LMaterial.m_Smoothness = PyFetchNumericType(value); - } - else if (propertyName == "Specular Level") - { - const float localVariableAlpha = PyFetchNumericType(value); - ColorF colorFloat = pMaterial->GetShaderResources().m_LMaterial.m_Specular; - colorFloat.r *= localVariableAlpha; - colorFloat.g *= localVariableAlpha; - colorFloat.b *= localVariableAlpha; - colorFloat.a = 1.0f; - pMaterial->GetShaderResources().m_LMaterial.m_Specular = colorFloat; - } - else if (propertyName == "Emissive Color") - { - const AZ::Color* color = AZStd::any_cast(&value); - float emissiveIntensity = pMaterial->GetShaderResources().m_LMaterial.m_Emittance.a; - pMaterial->GetShaderResources().m_LMaterial.m_Emittance = ColorGammaToLinear(QColor(color->GetR8(), color->GetG8(), color->GetB8())); - pMaterial->GetShaderResources().m_LMaterial.m_Emittance.a = emissiveIntensity; - } - else if (propertyName == "Emissive Intensity") - { - pMaterial->GetShaderResources().m_LMaterial.m_Emittance.a = PyFetchNumericType(value); - } - } - // ########## Advanced ########## - else if (categoryName == "Advanced") - { - if (propertyName == "Allow layer activation") - { - pMaterial->SetLayerActivation(PyFetchNumericType(value)); - } - else if (propertyName == "2 Sided") - { - SetMaterialFlag(pMaterial, MTL_FLAG_2SIDED, PyFetchNumericType(value)); - } - else if (propertyName == "No Shadow") - { - SetMaterialFlag(pMaterial, MTL_FLAG_NOSHADOW, PyFetchNumericType(value)); - } - else if (propertyName == "Use Scattering") - { - SetMaterialFlag(pMaterial, MTL_FLAG_SCATTER, PyFetchNumericType(value)); - } - else if (propertyName == "Hide After Breaking") - { - SetMaterialFlag(pMaterial, MTL_FLAG_HIDEONBREAK, PyFetchNumericType(value)); - } - else if (propertyName == "Fog Volume Shading Quality High") - { - SetMaterialFlag(pMaterial, MTL_FLAG_FOG_VOLUME_SHADING_QUALITY_HIGH, PyFetchNumericType(value)); - } - else if (propertyName == "Blend Terrain Color") - { - SetMaterialFlag(pMaterial, MTL_FLAG_BLEND_TERRAIN, PyFetchNumericType(value)); - } - else if (propertyName == "Voxel Coverage") - { - pMaterial->GetShaderResources().m_VoxelCoverage = aznumeric_cast(PyFetchNumericType(value) * 255.0f); - } - else if (propertyName == "Link to Material") - { - pMaterial->GetMatInfo()->SetMaterialLinkName(AZStd::any_cast(value).data()); - } - else if (propertyName == "Propagate Material Settings") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_MATERIAL_SETTINGS, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Opacity Settings") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_OPACITY, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Lighting Settings") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_LIGHTING, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Advanced Settings") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_ADVANCED, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Texture Maps") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_TEXTURES, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Shader Params") - { - if (PyFetchNumericType(value)) - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_MATERIAL_SETTINGS, true); - } - SetPropagationFlag(pMaterial, MTL_PROPAGATE_SHADER_PARAMS, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Shader Generation") - { - if (PyFetchNumericType(value)) - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_MATERIAL_SETTINGS, true); - } - SetPropagationFlag(pMaterial, MTL_PROPAGATE_SHADER_GEN, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Vertex Deformation") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_VERTEX_DEF, PyFetchNumericType(value)); - } - else if (propertyName == "Propagate Layer Presets") - { - SetPropagationFlag(pMaterial, MTL_PROPAGATE_LAYER_PRESETS, PyFetchNumericType(value)); - } - } - // ########## Texture Maps ########## - else if (categoryName == "Texture Maps") - { - // ########## Texture Maps / [name] ########## - SInputShaderResources& shaderResources = pMaterial->GetShaderResources(); - if (splittedPropertyPath.size() == 2) - { - uint16 nSlot = aznumeric_cast(TryConvertingCStringToEEfResTextures(propertyName)); - auto stringValue = AZStd::any_cast(value); - if (stringValue.empty()) - { - AZ_Warning("ShadersSystem", false, "PySetProperty - Error: empty texture [%d] name for material %s", - nSlot, pMaterial->GetName().toStdString().c_str()); - } - // notice that the following is an insertion operation if the index did not exist in the map - shaderResources.m_TexturesResourcesMap[nSlot].m_Name = stringValue.data(); - } - // ########## Texture Maps / [TexType | Filter | IsProjectedTexGen | TexGenType ] ########## - else if (splittedPropertyPath.size() == 3) - { - uint16 nSlot = aznumeric_cast(TryConvertingCStringToEEfResTextures(subCategoryName)); - // notice that each of the following will add the texture slot if did not exist yet - if (propertyName == "TexType") - { - shaderResources.m_TexturesResourcesMap[nSlot].m_Sampler.m_eTexType = TryConvertingCStringToETEX_Type(AZStd::any_cast(value)); - } - else if (propertyName == "Filter") - { - shaderResources.m_TexturesResourcesMap[nSlot].m_Filter = TryConvertingCStringToTexFilter(AZStd::any_cast(value)); - } - else if (propertyName == "IsProjectedTexGen") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_bTexGenProjected = PyFetchNumericType(value); - } - else if (propertyName == "TexGenType") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_eTGType = TryConvertingCStringToETexGenType(AZStd::any_cast(value)); - } - } - // ########## Texture Maps / [Tiling | Rotator | Oscillator] ########## - else if (splittedPropertyPath.size() == 4) - { - uint16 nSlot = aznumeric_cast(TryConvertingCStringToEEfResTextures(subSubCategoryName)); - if (subCategoryName == "Tiling") - { - if (propertyName == "IsTileU") - { - shaderResources.m_TexturesResourcesMap[nSlot].m_bUTile = PyFetchNumericType(value); - } - else if (propertyName == "IsTileV") - { - shaderResources.m_TexturesResourcesMap[nSlot].m_bVTile = PyFetchNumericType(value); - } - else if (propertyName == "TileU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Tiling[0] = PyFetchNumericType(value); - } - else if (propertyName == "TileV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Tiling[1] = PyFetchNumericType(value); - } - else if (propertyName == "OffsetU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Offs[0] = PyFetchNumericType(value); - } - else if (propertyName == "OffsetV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Offs[1] = PyFetchNumericType(value); - } - else if (propertyName == "RotateU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Rot[0] = Degr2Word(PyFetchNumericType(value)); - } - else if (propertyName == "RotateV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Rot[1] = Degr2Word(PyFetchNumericType(value)); - } - else if (propertyName == "RotateW") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_Rot[2] = Degr2Word(PyFetchNumericType(value)); - } - } - else if (subCategoryName == "Rotator") - { - if (propertyName == "Type") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_eRotType = TryConvertingCStringToETexModRotateType(AZStd::any_cast(value)); - } - else if (propertyName == "Rate") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_RotOscRate[2] = Degr2Word(PyFetchNumericType(value)); - } - else if (propertyName == "Phase") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_RotOscPhase[2] = Degr2Word(PyFetchNumericType(value)); - } - else if (propertyName == "Amplitude") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_RotOscAmplitude[2] = Degr2Word(PyFetchNumericType(value)); - } - else if (propertyName == "CenterU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_RotOscCenter[0] = PyFetchNumericType(value); - } - else if (propertyName == "CenterV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_RotOscCenter[1] = PyFetchNumericType(value); - } - } - else if (subCategoryName == "Oscillator") - { - if (propertyName == "TypeU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_eMoveType[0] = TryConvertingCStringToETexModMoveType(AZStd::any_cast(value)); - } - else if (propertyName == "TypeV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_eMoveType[1] = TryConvertingCStringToETexModMoveType(AZStd::any_cast(value)); - } - else if (propertyName == "RateU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscRate[0] = PyFetchNumericType(value); - } - else if (propertyName == "RateV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscRate[1] = PyFetchNumericType(value); - } - else if (propertyName == "PhaseU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscPhase[0] = PyFetchNumericType(value); - } - else if (propertyName == "PhaseV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscPhase[1] = PyFetchNumericType(value); - } - else if (propertyName == "AmplitudeU") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscAmplitude[0] = PyFetchNumericType(value); - } - else if (propertyName == "AmplitudeV") - { - shaderResources.m_TexturesResourcesMap[nSlot].AddModificator()->m_OscAmplitude[1] = PyFetchNumericType(value); - } - } - } - } - // ########## Shader Params ########## - else if (categoryName == "Shader Params") - { - auto& shaderParams = pMaterial->GetShaderResources().m_ShaderParams; - - for (int i = 0; i < shaderParams.size(); i++) - { - if (propertyName == ParseUINameFromPublicParamsScript(shaderParams[i].m_Script.c_str())) - { - if (shaderParams[i].m_Type == eType_FLOAT) - { - shaderParams[i].m_Value.m_Float = PyFetchNumericType(value); - break; - } - else if (shaderParams[i].m_Type == eType_FCOLOR) - { - const AZ::Color* color = AZStd::any_cast(&value); - ColorF colorLinear = ColorGammaToLinear(QColor(color->GetR8(), color->GetG8(), color->GetB8())); - shaderParams[i].m_Value.m_Vector[0] = colorLinear.r; - shaderParams[i].m_Value.m_Vector[1] = colorLinear.g; - shaderParams[i].m_Value.m_Vector[2] = colorLinear.b; - break; - } - else - { - throw std::runtime_error("Invalid data type (Shader Params)"); - } - } - } - } - // ########## Shader Generation Params ########## - else if (categoryName == "Shader Generation Params") - { - for (int i = 0; i < pMaterial->GetShaderGenParamsVars()->GetNumVariables(); i++) - { - if (propertyName == pMaterial->GetShaderGenParamsVars()->GetVariable(i)->GetHumanName()) - { - CVarBlock* shaderGenBlock = pMaterial->GetShaderGenParamsVars(); - shaderGenBlock->GetVariable(i)->Set(PyFetchNumericType(value)); - pMaterial->SetShaderGenParamsVars(shaderGenBlock); - break; - } - } - } - // ########## Vertex Deformation ########## - else if (categoryName == "Vertex Deformation") - { - // ########## Vertex Deformation / [ Type | Wave Length X | Noise Scale ] ########## - if (splittedPropertyPath.size() == 2) - { - if (propertyName == "Type") - { - pMaterial->GetShaderResources().m_DeformInfo.m_eType = TryConvertingCStringToEDeformType(AZStd::any_cast(value)); - } - else if (propertyName == "Wave Length X") - { - pMaterial->GetShaderResources().m_DeformInfo.m_fDividerX = PyFetchNumericType(value); - } - else if (propertyName == "Noise Scale") - { - const AZ::Vector3* vecValue = AZStd::any_cast(&value); - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[0] = vecValue->GetX(); - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[1] = vecValue->GetY(); - pMaterial->GetShaderResources().m_DeformInfo.m_vNoiseScale[2] = vecValue->GetZ(); - } - } - // ########## Vertex Deformation / [ Wave X ] ########## - else if (splittedPropertyPath.size() == 3) - { - if (subCategoryName == "Wave X") - { - SWaveForm2& currentWaveForm = pMaterial->GetShaderResources().m_DeformInfo.m_WaveX; - - if (propertyName == "Type") - { - currentWaveForm.m_eWFType = TryConvertingCStringToEWaveForm(AZStd::any_cast(value)); - } - else if (propertyName == "Level") - { - currentWaveForm.m_Level = PyFetchNumericType(value); - } - else if (propertyName == "Amplitude") - { - currentWaveForm.m_Amp = PyFetchNumericType(value); - } - else if (propertyName == "Phase") - { - currentWaveForm.m_Phase = PyFetchNumericType(value); - } - else if (propertyName == "Frequency") - { - currentWaveForm.m_Freq = PyFetchNumericType(value); - } - } - } - } - // ########## Layer Presets ########## - else if (categoryName == "Layer Presets") - { - // names are "Shader1", "Shader2" and "Shader3", because all have the name "Shader" in material editor - if (splittedPropertyPath.size() == 2) - { - int shaderNumber = -1; - if (propertyName == "Shader1") - { - shaderNumber = 0; - } - else if (propertyName == "Shader2") - { - shaderNumber = 1; - } - else if (propertyName == "Shader3") - { - shaderNumber = 2; - } - - pMaterial->GetMtlLayerResources()[shaderNumber].m_shaderName = AZStd::any_cast(value).data(); - } - else if (splittedPropertyPath.size() == 3) - { - if (propertyName == "No Draw") - { - int shaderNumber = -1; - if (subCategoryName == "Shader1") - { - shaderNumber = 0; - } - else if (subCategoryName == "Shader2") - { - shaderNumber = 1; - } - else if (subCategoryName == "Shader3") - { - shaderNumber = 2; - } - - if (pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags & MTL_LAYER_USAGE_NODRAW && PyFetchNumericType(value) == false) - { - pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags = pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags - MTL_LAYER_USAGE_NODRAW; - } - else if (!(pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags & MTL_LAYER_USAGE_NODRAW) && PyFetchNumericType(value) == true) - { - pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags = pMaterial->GetMtlLayerResources()[shaderNumber].m_nFlags | MTL_LAYER_USAGE_NODRAW; - } - } - } - } - - pMaterial->Update(); - pMaterial->Save(); - GetIEditor()->GetMaterialManager()->OnUpdateProperties(pMaterial, true); - } -} - -namespace AzToolsFramework -{ - void MaterialPythonFuncsHandler::Reflect(AZ::ReflectContext* context) - { - if (auto behaviorContext = azrtti_cast(context)) - { - // this will put these methods into the 'azlmbr.legacy.material' module - auto addLegacyMaterial = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) - { - methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Category, "Legacy/Material") - ->Attribute(AZ::Script::Attributes::Module, "legacy.material"); - }; - addLegacyMaterial(behaviorContext->Method("create", PyMaterialCreate, nullptr, "Creates a material.")); - addLegacyMaterial(behaviorContext->Method("create_multi", PyMaterialCreateMulti, nullptr, "Creates a multi-material.")); - addLegacyMaterial(behaviorContext->Method("convert_to_multi", PyMaterialConvertToMulti, nullptr, "Converts the selected material to a multi-material.")); - addLegacyMaterial(behaviorContext->Method("duplicate_current", PyMaterialDuplicateCurrent, nullptr, "Duplicates the current material.")); - addLegacyMaterial(behaviorContext->Method("merge_selection", PyMaterialMergeSelection, nullptr, "Merges the selected materials.")); - addLegacyMaterial(behaviorContext->Method("delete_current", PyMaterialDeleteCurrent, nullptr, "Deletes the current material.")); - addLegacyMaterial(behaviorContext->Method("get_submaterial", PyGetSubMaterial, nullptr, "Gets sub materials of a material.")); - addLegacyMaterial(behaviorContext->Method("get_property", PyGetProperty, nullptr, "Gets a property of a material.")); - addLegacyMaterial(behaviorContext->Method("set_property", PySetProperty, nullptr, "Sets a property of a material.")); - } - } -} diff --git a/Code/Sandbox/Editor/Material/MaterialPythonFuncs.h b/Code/Sandbox/Editor/Material/MaterialPythonFuncs.h deleted file mode 100644 index f04542f466..0000000000 --- a/Code/Sandbox/Editor/Material/MaterialPythonFuncs.h +++ /dev/null @@ -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 - -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 diff --git a/Code/Sandbox/Editor/Material/PreviewModelView.cpp b/Code/Sandbox/Editor/Material/PreviewModelView.cpp deleted file mode 100644 index 41a50436d1..0000000000 --- a/Code/Sandbox/Editor/Material/PreviewModelView.cpp +++ /dev/null @@ -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 - -//CRY -#include -#include - -//Editor -#include -#include -#include -#include -#include -#include -#include -#include - -//EditorCommon -#include - -//Local -#include "PreviewModelView.h" - -//QT -#include - - - -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(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(flag)); -} - -void CPreviewModelView::UnSetFlag(PreviewModelViewFlag flag) -{ - CRY_ASSERT(flag < PreviewModelViewFlag::END_POSSIBLE_ITEMS); - m_Flags &= ~(1 << static_cast(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 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; -} - diff --git a/Code/Sandbox/Editor/Material/PreviewModelView.h b/Code/Sandbox/Editor/Material/PreviewModelView.h deleted file mode 100644 index 3d27983be1..0000000000 --- a/Code/Sandbox/Editor/Material/PreviewModelView.h +++ /dev/null @@ -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 PostUpdateCallback; - void SetPostUpdateCallback(PostUpdateCallback callback); - - typedef std::function 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; -}; diff --git a/Code/Sandbox/Editor/Material/images/filestatus_00.png b/Code/Sandbox/Editor/Material/images/filestatus_00.png deleted file mode 100644 index 414609f486..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e5d226d043630028a1fe88af240b627a08966066b605294cc79ff8273588166 -size 194 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_01.png b/Code/Sandbox/Editor/Material/images/filestatus_01.png deleted file mode 100644 index d644fcfe12..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f80544a0537398979dd423ffdc8e99c08e47dbe814cd4225646761cbe281eecc -size 206 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_02.png b/Code/Sandbox/Editor/Material/images/filestatus_02.png deleted file mode 100644 index da155a1d2a..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bee8a3d1d5571e5afe0bd02edf0fc58d8297f96494a7c074fd2a37ecda7ae4dc -size 208 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_03.png b/Code/Sandbox/Editor/Material/images/filestatus_03.png deleted file mode 100644 index a047cb4599..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d3d0fc234e3154c06abd4e3b8d3d7e52a75f80d527b1d05541f55221cba199d7 -size 183 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_04.png b/Code/Sandbox/Editor/Material/images/filestatus_04.png deleted file mode 100644 index 519b68d500..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ffb3586ef4309d8bfa93a581c38fe970e8b0411f170955921054522b0bf52bd3 -size 182 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_05.png b/Code/Sandbox/Editor/Material/images/filestatus_05.png deleted file mode 100644 index f4f548cdc9..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f258e9617a1d4c7be16fcab12533a4f0bfe4072151f2140ca41364ef1a3cea62 -size 196 diff --git a/Code/Sandbox/Editor/Material/images/filestatus_06.png b/Code/Sandbox/Editor/Material/images/filestatus_06.png deleted file mode 100644 index 7b7412b19d..0000000000 --- a/Code/Sandbox/Editor/Material/images/filestatus_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:68c609d7bde1796f281690148c19694afddcc2cf4ea306116b546327cb50aad2 -size 249 diff --git a/Code/Sandbox/Editor/Material/images/material_00.png b/Code/Sandbox/Editor/Material/images/material_00.png deleted file mode 100644 index a7f48148f1..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd5106eebb6cf264fdac5f3568977fc8f944df4a4d4de6b0e9f35b3a001a3001 -size 206 diff --git a/Code/Sandbox/Editor/Material/images/material_01.png b/Code/Sandbox/Editor/Material/images/material_01.png deleted file mode 100644 index e6c26f748a..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2b08a8d94c64aed944901b76afcb921c3df2c122c9eac6d52140552c2eb4e5cc -size 227 diff --git a/Code/Sandbox/Editor/Material/images/material_02.png b/Code/Sandbox/Editor/Material/images/material_02.png deleted file mode 100644 index a116e84295..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:623a937f09f1de3ebb889d7ac9e042f91bf67bef34695801b3603f4517166c8e -size 223 diff --git a/Code/Sandbox/Editor/Material/images/material_03.png b/Code/Sandbox/Editor/Material/images/material_03.png deleted file mode 100644 index a116e84295..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:623a937f09f1de3ebb889d7ac9e042f91bf67bef34695801b3603f4517166c8e -size 223 diff --git a/Code/Sandbox/Editor/Material/images/material_04.png b/Code/Sandbox/Editor/Material/images/material_04.png deleted file mode 100644 index 1d83e3526a..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0ad56ab7be0a5a40b644045ac01c90fed6e70433a693e80c5b4b88d63801d75f -size 14604 diff --git a/Code/Sandbox/Editor/Material/images/material_05.png b/Code/Sandbox/Editor/Material/images/material_05.png deleted file mode 100644 index 8d953a6ae4..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9cc845c4eb0ed6fb772064d73f1c679e3b28288411a02f0cafaf248b83b44ca2 -size 221 diff --git a/Code/Sandbox/Editor/Material/images/material_06.png b/Code/Sandbox/Editor/Material/images/material_06.png deleted file mode 100644 index 7e5159a2fc..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:966fd5ef5c1e0fe6e920511952d7aea98ad0f165f9ce0197f000f9f48ccd338b -size 14628 diff --git a/Code/Sandbox/Editor/Material/images/material_07.png b/Code/Sandbox/Editor/Material/images/material_07.png deleted file mode 100644 index 7e5159a2fc..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:966fd5ef5c1e0fe6e920511952d7aea98ad0f165f9ce0197f000f9f48ccd338b -size 14628 diff --git a/Code/Sandbox/Editor/Material/images/material_browser_00.png b/Code/Sandbox/Editor/Material/images/material_browser_00.png deleted file mode 100644 index f1e7a2ffce..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_browser_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4a8dc85c9928faacd184148aaf0f17ef7b68c185b04b0b5f16e942fb11c528e -size 209 diff --git a/Code/Sandbox/Editor/Material/images/material_browser_01.png b/Code/Sandbox/Editor/Material/images/material_browser_01.png deleted file mode 100644 index 1ff2ea213f..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_browser_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d9047378404e0893b79bafaad9e6b312d467033daab2191a8c8839e4ff494bd8 -size 321 diff --git a/Code/Sandbox/Editor/Material/images/material_browser_02.png b/Code/Sandbox/Editor/Material/images/material_browser_02.png deleted file mode 100644 index edd5148133..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_browser_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e79122edef52c3f9a31fd662f9f5cfd08b06e44e861c7379d8869635fd1d245 -size 168 diff --git a/Code/Sandbox/Editor/Material/images/material_browser_03.png b/Code/Sandbox/Editor/Material/images/material_browser_03.png deleted file mode 100644 index bfbcc6ce98..0000000000 --- a/Code/Sandbox/Editor/Material/images/material_browser_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8cc16bbb4c4c0c1bea14c94d0609f4b11a7cd0ead4af3d236d329a404e8223a8 -size 200 diff --git a/Code/Sandbox/Editor/MaterialSender.cpp b/Code/Sandbox/Editor/MaterialSender.cpp deleted file mode 100644 index 2123eadb31..0000000000 --- a/Code/Sandbox/Editor/MaterialSender.cpp +++ /dev/null @@ -1,60 +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 "MaterialSender.h" - -bool CMaterialSender::SendMessage(int msg, const XmlNodeRef& node) -{ - bool bRet = false; - -#if defined(AZ_PLATFORM_WINDOWS) - if (!CheckWindows()) - { - return false; - } - - m_h.msg = msg; - - int nDataSize = sizeof(SMaterialMapFileHeader) + strlen(node->getXML().c_str()) + 1; - - //hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, nDataSize, "EditMatMappingObject"); - - HANDLE mapFileHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "EditMatMappingObject"); - if (mapFileHandle) - { - void* pMes = MapViewOfFile(mapFileHandle, FILE_MAP_ALL_ACCESS, 0, 0, nDataSize); - if (pMes) - { - memcpy(pMes, &m_h, sizeof(SMaterialMapFileHeader)); - azstrcpy(((char*)pMes) + sizeof(SMaterialMapFileHeader), nDataSize - sizeof(SMaterialMapFileHeader), node->getXML().c_str()); - UnmapViewOfFile(pMes); - if (m_bIsMatEditor) - { - ::SendMessage(m_h.GetMaxHWND(), WM_MATEDITSEND, msg, 0); - } - else - { - ::SendMessage(m_h.GetEditorHWND(), WM_MATEDITSEND, msg, 0); - } - bRet = true; - } - CloseHandle(mapFileHandle); - } - else - { - CryLog("No File Map"); - } -#endif - - return bRet; -} diff --git a/Code/Sandbox/Editor/MaterialSender.h b/Code/Sandbox/Editor/MaterialSender.h deleted file mode 100644 index 0123223821..0000000000 --- a/Code/Sandbox/Editor/MaterialSender.h +++ /dev/null @@ -1,175 +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_MATERIALSENDER_H -#define CRYINCLUDE_EDITOR_MATERIALSENDER_H -#pragma once - -#ifndef WM_MATEDITSEND -// Value copied from Code/Tools/MaxCryExport/CryShader/MaterialSender.h -# define WM_MATEDITSEND (WM_USER + 315) -#endif - -enum EMaterialSenderMessage -{ - eMSM_Create = 1, - eMSM_GetSelectedMaterial = 2, - eMSM_Init = 3, -}; - -#if defined(AZ_PLATFORM_WINDOWS) -struct SMaterialMapFileHeader -{ - // max - void SetMaxHWND(HWND hWnd) - { - hwndMax = (int64)hWnd; - } - HWND GetMaxHWND() const - { - return (HWND)hwndMax; - } - // editor - void SetEditorHWND(HWND hWnd) - { - hwndMatEdit = (int64)hWnd; - } - HWND GetEditorHWND() const - { - return (HWND)hwndMatEdit; - } - int64 msg;// 64bits for both 32 and 64 - int64 Reserved;// 64bits for both 32 and 64 -protected: - uint64 hwndMax;// HWND for 32 and 64 is different - uint64 hwndMatEdit;// HWND for 32 and 64 is different -}; -#endif // AZ_PLATFORM_WINDOWS - - -class CMaterialSender -{ -public: - - CMaterialSender(bool bIsMatEditor) - : m_bIsMatEditor(bIsMatEditor) - { -#if defined(AZ_PLATFORM_WINDOWS) - m_h.SetEditorHWND(0); - m_h.SetMaxHWND(0); - m_h.msg = 0; - hMapFile = 0; -#endif - } - - ~CMaterialSender() - { -#if defined(AZ_PLATFORM_WINDOWS) - if (hMapFile) - { - CloseHandle(hMapFile); - } - hMapFile = 0; -#endif - } - - bool GetMessage() - { - LoadMapFile(); - return true; - } - - bool CheckWindows() - { -#if defined(AZ_PLATFORM_WINDOWS) - if (!m_h.GetMaxHWND() || !m_h.GetEditorHWND() || !::IsWindow(m_h.GetMaxHWND()) || !::IsWindow(m_h.GetEditorHWND())) - { - LoadMapFile(); - } - if (!m_h.GetMaxHWND() || !m_h.GetEditorHWND() || !::IsWindow(m_h.GetMaxHWND()) || !::IsWindow(m_h.GetEditorHWND())) - { - return false; - } -#endif - return true; - } - - bool Create() - { -#if defined(AZ_PLATFORM_WINDOWS) - hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 1024 * 1024, "EditMatMappingObject"); - if (hMapFile) - { - return true; - } - CryLog("Can't create File Map"); - - return false; -#else - return true; -#endif - } - - bool SendMessage(int msg, const XmlNodeRef& node); - - void SetupWindows(QWidget* hwndMax, QWidget* hwndMatEdit) - { -#if defined(AZ_PLATFORM_WINDOWS) - m_h.SetMaxHWND(reinterpret_cast(hwndMax->winId())); - m_h.SetEditorHWND(reinterpret_cast(hwndMatEdit->winId())); -#endif - } - -private: - - bool LoadMapFile() - { -#if defined(AZ_PLATFORM_WINDOWS) - bool bRet = false; - const HANDLE mapFileHandle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "EditMatMappingObject"); - if (mapFileHandle) - { - void* const pMes = MapViewOfFile(mapFileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0); - - if (pMes) - { - memcpy(&m_h, pMes, sizeof(SMaterialMapFileHeader)); - const char* const pXml = ((const char*)pMes) + sizeof(SMaterialMapFileHeader); - m_node = XmlHelpers::LoadXmlFromBuffer(pXml, strlen(pXml)); - UnmapViewOfFile(pMes); - bRet = true; - } - - CloseHandle(mapFileHandle); - } - - return bRet; -#else - return false; -#endif - } - -public: -#if defined(AZ_PLATFORM_WINDOWS) - SMaterialMapFileHeader m_h; -#endif - XmlNodeRef m_node; -private: - bool m_bIsMatEditor; -#if defined(AZ_PLATFORM_WINDOWS) - HANDLE hMapFile; -#endif -}; - - -#endif // CRYINCLUDE_EDITOR_MATERIALSENDER_H diff --git a/Code/Sandbox/Editor/ModelViewport.cpp b/Code/Sandbox/Editor/ModelViewport.cpp index bf15f2fbaf..2e00adb4fc 100644 --- a/Code/Sandbox/Editor/ModelViewport.cpp +++ b/Code/Sandbox/Editor/ModelViewport.cpp @@ -29,7 +29,6 @@ // Editor #include "ThumbnailGenerator.h" // for CThumbnailGenerator #include "FileTypeUtils.h" // for IsPreviewableFileType -#include "Material/MaterialManager.h" // for CMaterialManager #include "ErrorRecorder.h" @@ -652,32 +651,6 @@ void CModelViewport::DrawInfo() const } } -////////////////////////////////////////////////////////////////////////// -void CModelViewport::SetCustomMaterial(CMaterial* pMaterial) -{ - m_pCurrentMaterial = pMaterial; -} - -////////////////////////////////////////////////////////////////////////// -CMaterial* CModelViewport::GetMaterial() -{ - if (m_pCurrentMaterial) - { - return m_pCurrentMaterial; - } - else - { - _smart_ptr pMtl = 0; - if (m_object) - { - pMtl = m_object->GetMaterial(); - } - - CMaterial* pCMaterial = GetIEditor()->GetMaterialManager()->FromIMaterial(pMtl); - return pCMaterial; - } -} - ////////////////////////////////////////////////////////////////////////// bool CModelViewport::CanDrop([[maybe_unused]] const QPoint& point, IDataBaseItem* pItem) { @@ -686,26 +659,12 @@ bool CModelViewport::CanDrop([[maybe_unused]] const QPoint& point, IDataBaseItem return false; } - if (pItem->GetType() == EDB_TYPE_MATERIAL) - { - SetCustomMaterial((CMaterial*)pItem); - } return true; } ////////////////////////////////////////////////////////////////////////// -void CModelViewport::Drop([[maybe_unused]] const QPoint& point, IDataBaseItem* pItem) +void CModelViewport::Drop([[maybe_unused]] const QPoint& point, [[maybe_unused]] IDataBaseItem* pItem) { - if (!pItem) - { - SetCustomMaterial(NULL); - return; - } - - if (pItem->GetType() == EDB_TYPE_MATERIAL) - { - SetCustomMaterial((CMaterial*)pItem); - } } ////////////////////////////////////////////////////////////////////////// @@ -788,10 +747,6 @@ void CModelViewport::DrawModel(const SRenderingPassInfo& passInfo) } rp.dwFObjFlags = 0; - if (m_pCurrentMaterial) - { - rp.pMaterial = m_pCurrentMaterial->GetMatInfo(); - } //----------------------------------------------------------------------------- //----- Render Static Object (handled by 3DEngine) ---- diff --git a/Code/Sandbox/Editor/ModelViewport.h b/Code/Sandbox/Editor/ModelViewport.h index d9b119c5d5..a5d1ac2a26 100644 --- a/Code/Sandbox/Editor/ModelViewport.h +++ b/Code/Sandbox/Editor/ModelViewport.h @@ -31,7 +31,6 @@ #if !defined(Q_MOC_RUN) #include "RenderViewport.h" -#include "Material/Material.h" #include "Util/Variable.h" #endif @@ -90,14 +89,6 @@ public: void UseWeaponIK([[maybe_unused]] bool val) { m_weaponIK = true; } - // Set current material to render object. - void SetCustomMaterial(CMaterial* pMaterial); - // Get custom material that object is rendered with. - CMaterial* GetCustomMaterial() { return m_pCurrentMaterial; }; - - // Get material the object is actually rendered with. - CMaterial* GetMaterial(); - void ReleaseObject(); void RePhysicalize(); @@ -182,7 +173,6 @@ protected: class CRESky* m_pRESky; struct ICVar* m_pSkyboxName; IShader* m_pSkyBoxShader; - _smart_ptr m_pCurrentMaterial; //--------------------------------------------------- //--- debug options --- diff --git a/Code/Sandbox/Editor/Objects/AxisGizmo.cpp b/Code/Sandbox/Editor/Objects/AxisGizmo.cpp index 40970838c1..ef2b91685a 100644 --- a/Code/Sandbox/Editor/Objects/AxisGizmo.cpp +++ b/Code/Sandbox/Editor/Objects/AxisGizmo.cpp @@ -22,7 +22,6 @@ #include "ViewManager.h" #include "Settings.h" #include "RenderHelpers/AxisHelper.h" -#include "RenderHelpers/AxisHelperExtended.h" #include "IObjectManager.h" ////////////////////////////////////////////////////////////////////////// @@ -36,7 +35,6 @@ CAxisGizmo::CAxisGizmo(CBaseObject* object) assert(object != 0); m_object = object; m_pAxisHelper.reset(new CAxisHelper); - m_pAxisHelperExtended.reset(new CAxisHelperExtended); // Set selectable flag. SetFlags(EGIZMO_SELECTABLE | EGIZMO_TRANSFORM_MANIPULATOR); @@ -60,7 +58,6 @@ CAxisGizmo::CAxisGizmo() SetFlags(EGIZMO_SELECTABLE); m_axisGizmoCount++; m_pAxisHelper.reset(new CAxisHelper); - m_pAxisHelperExtended.reset(new CAxisHelperExtended); m_bDragging = false; m_bAlwaysUseLocal = false; m_coordSysBackUp = COORDS_VIEW; diff --git a/Code/Sandbox/Editor/Objects/AxisGizmo.h b/Code/Sandbox/Editor/Objects/AxisGizmo.h index 55506ed6b5..689b011972 100644 --- a/Code/Sandbox/Editor/Objects/AxisGizmo.h +++ b/Code/Sandbox/Editor/Objects/AxisGizmo.h @@ -22,7 +22,6 @@ // forward declarations. struct DisplayContext; class CAxisHelper; -class CAxisHelperExtended; /** Gizmo of Objects animation track. */ @@ -75,7 +74,6 @@ private: CBaseObjectPtr m_object; AABB m_bbox; std::unique_ptr m_pAxisHelper; - std::unique_ptr m_pAxisHelperExtended; bool m_bDragging; QPoint m_cMouseDownPos; diff --git a/Code/Sandbox/Editor/Objects/BaseObject.cpp b/Code/Sandbox/Editor/Objects/BaseObject.cpp index a579f303a9..109b28798f 100644 --- a/Code/Sandbox/Editor/Objects/BaseObject.cpp +++ b/Code/Sandbox/Editor/Objects/BaseObject.cpp @@ -30,8 +30,6 @@ #include "DisplaySettings.h" #include "Undo/Undo.h" #include "UsedResources.h" -#include "Material/Material.h" -#include "Material/MaterialManager.h" #include "GizmoManager.h" #include "Include/IIconManager.h" #include "Objects/SelectionGroup.h" @@ -398,7 +396,6 @@ CBaseObject::CBaseObject() , m_classDesc(nullptr) , m_numRefs(0) , m_parent(nullptr) - , m_pMaterial(nullptr) , m_bInSelectionBox(false) , m_pTransformDelegate(nullptr) , m_bMatrixInWorldSpace(false) @@ -438,7 +435,6 @@ bool CBaseObject::Init([[maybe_unused]] IEditor* ie, CBaseObject* prev, [[maybe_ SetArea(prev->GetArea()); SetColor(prev->GetColor()); m_nMaterialLayersMask = prev->m_nMaterialLayersMask; - SetMaterial(prev->GetMaterial()); SetMinSpec(prev->GetMinSpec(), false); // Copy all basic variables. @@ -485,12 +481,6 @@ void CBaseObject::Done() NotifyListeners(CBaseObject::ON_DELETE); m_eventListeners.clear(); - - if (m_pMaterial) - { - m_pMaterial->Release(); - m_pMaterial = NULL; - } } ////////////////////////////////////////////////////////////////////////// @@ -1838,11 +1828,6 @@ void CBaseObject::Serialize(CObjectArchive& ar) SetFrozen(bFrozen); SetHidden(bHidden); - ////////////////////////////////////////////////////////////////////////// - // Load material. - ////////////////////////////////////////////////////////////////////////// - SetMaterial(mtlName); - ar.SetResolveCallback(this, parentId, AZStd::bind(&CBaseObject::ResolveParent, this, AZStd::placeholders::_1 )); ar.SetResolveCallback(this, lookatId, AZStd::bind(&CBaseObject::SetLookAt, this, AZStd::placeholders::_1)); @@ -1912,11 +1897,6 @@ void CBaseObject::Serialize(CObjectArchive& ar) xmlNode->setAttr("Flags", flags); } - if (m_pMaterial) - { - xmlNode->setAttr("Material", GetMaterialName().toUtf8().data()); - } - if (m_nMinSpec != 0) { xmlNode->setAttr("MinSpec", (uint32)m_nMinSpec); @@ -1937,11 +1917,6 @@ XmlNodeRef CBaseObject::Export([[maybe_unused]] const QString& levelPath, XmlNod objNode->setAttr("Type", GetTypeName().toUtf8().data()); objNode->setAttr("Name", GetName().toUtf8().data()); - if (m_pMaterial) - { - objNode->setAttr("Material", m_pMaterial->GetName().toUtf8().data()); - } - Vec3 pos, scale; Quat rotate; if (m_parent) @@ -2926,7 +2901,6 @@ bool CBaseObject::ConvertFromObject(CBaseObject* object) { object->GetParent()->AttachChild(this); } - SetMaterial(object->GetMaterial()); return true; } @@ -2981,14 +2955,6 @@ void CBaseObject::Validate(IErrorReport* report) report->ReportError(err); } ////////////////////////////////////////////////////////////////////////// - - if (GetMaterial() != NULL && GetMaterial()->IsDummy()) - { - CErrorRecord err; - err.error = QStringLiteral("Material: %1 for object: %2 not found,").arg(GetMaterial()->GetName(), GetName()); - err.pObject = this; - report->ReportError(err); - } }; ////////////////////////////////////////////////////////////////////////// @@ -3055,10 +3021,6 @@ void CBaseObject::GatherUsedResources(CUsedResources& resources) { GetVarBlock()->GatherUsedResources(resources); } - if (m_pMaterial) - { - m_pMaterial->GatherUsedResources(resources); - } } ////////////////////////////////////////////////////////////////////////// @@ -3071,50 +3033,6 @@ bool CBaseObject::IsSimilarObject(CBaseObject* pObject) return false; } -////////////////////////////////////////////////////////////////////////// -void CBaseObject::SetMaterial(CMaterial* mtl) -{ - if (m_pMaterial == mtl) - { - return; - } - - StoreUndo("Assign Material"); - if (m_pMaterial) - { - m_pMaterial->Release(); - } - m_pMaterial = mtl; - if (m_pMaterial) - { - m_pMaterial->AddRef(); - } - - OnMaterialChanged(MATERIALCHANGE_ALL); -} - -////////////////////////////////////////////////////////////////////////// -QString CBaseObject::GetMaterialName() const -{ - if (m_pMaterial) - { - return m_pMaterial->GetName(); - } - return ""; -} - -////////////////////////////////////////////////////////////////////////// -void CBaseObject::SetMaterial(const QString& materialName) -{ - CMaterial* pMaterial = NULL; - CMaterialManager* pManager = GetIEditor()->GetMaterialManager(); - if (!materialName.isEmpty() && pManager != NULL) - { - pMaterial = pManager->LoadMaterial(materialName); - } - SetMaterial(pMaterial); -} - ////////////////////////////////////////////////////////////////////////// void CBaseObject::SetMinSpec(uint32 nSpec, bool bSetChildren) { diff --git a/Code/Sandbox/Editor/Objects/BaseObject.h b/Code/Sandbox/Editor/Objects/BaseObject.h index d62e0bed5f..44df1e5757 100644 --- a/Code/Sandbox/Editor/Objects/BaseObject.h +++ b/Code/Sandbox/Editor/Objects/BaseObject.h @@ -35,7 +35,6 @@ class CUndoBaseObject; class CObjectManager; class CGizmo; class CObjectArchive; -class CMaterial; class CEdGeometry; struct SSubObjSelectionModifyContext; struct SRayHitInfo; @@ -135,13 +134,6 @@ enum ObjectEditFlags OBJECT_COLLAPSE_OBJECTPANEL = 0x004 }; -/////////////////////////////////////////////////////////////////////////// -enum MaterialChangeFlags -{ - MATERIALCHANGE_SURFACETYPE = 0x001, - MATERIALCHANGE_ALL = 0xFFFFFFFF, -}; - ////////////////////////////////////////////////////////////////////////// //! Return values from CBaseObject::MouseCreateCallback method. enum MouseCreateResult @@ -554,22 +546,6 @@ public: //! Remove event listener callback. void RemoveEventListener(EventListener* listener); - ////////////////////////////////////////////////////////////////////////// - //! Material handling for this base object. - //! Override in derived classes. - ////////////////////////////////////////////////////////////////////////// - //! Assign new material to this object. - virtual void SetMaterial(CMaterial* mtl); - //! Assign new material to this object as a material name. - virtual void SetMaterial(const QString& materialName); - //! Get assigned material for this object. - virtual CMaterial* GetMaterial() const { return m_pMaterial; }; - // Get actual rendering material for this object. - virtual CMaterial* GetRenderMaterial() const { return m_pMaterial; }; - // Get the material name. Even though the material pointer is null, the material name can exist separately. - virtual QString GetMaterialName() const; - virtual void OnMaterialChanged([[maybe_unused]] MaterialChangeFlags change) {} - ////////////////////////////////////////////////////////////////////////// //! Analyze errors for this object. virtual void Validate(IErrorReport* report); @@ -861,9 +837,6 @@ private: //! Pointer to parent node. mutable CBaseObject* m_parent; - //! Material of this object. - CMaterial* m_pMaterial; - AABB m_worldBounds; // The transform delegate diff --git a/Code/Sandbox/Editor/Objects/EntityObject.cpp b/Code/Sandbox/Editor/Objects/EntityObject.cpp index 82d45f8ae5..0b2627091c 100644 --- a/Code/Sandbox/Editor/Objects/EntityObject.cpp +++ b/Code/Sandbox/Editor/Objects/EntityObject.cpp @@ -25,7 +25,6 @@ #include "Settings.h" #include "Viewport.h" #include "LineGizmo.h" -#include "Material/MaterialManager.h" #include "Include/IObjectManager.h" #include "Objects/ObjectManager.h" #include "ViewManager.h" @@ -1077,11 +1076,6 @@ XmlNodeRef CEntityObject::Export([[maybe_unused]] const QString& levelPath, XmlN objNode->setAttr("Name", GetName().toUtf8().data()); - if (GetMaterial()) - { - objNode->setAttr("Material", GetMaterial()->GetName().toUtf8().data()); - } - Vec3 pos = GetPos(), scale = GetScale(); Quat rotate = GetRotation(); @@ -1860,17 +1854,6 @@ void CEntityObject::OnLoadFailed() GetIEditor()->GetErrorReport()->ReportError(err); } -////////////////////////////////////////////////////////////////////////// -CMaterial* CEntityObject::GetRenderMaterial() const -{ - if (GetMaterial()) - { - return GetMaterial(); - } - - return NULL; -} - ////////////////////////////////////////////////////////////////////////// void CEntityObject::SetHelperScale(float scale) { @@ -1943,21 +1926,6 @@ void CEntityObject::OnContextMenu(QMenu* pMenu) CBaseObject::OnContextMenu(pMenu); } -////////////////////////////////////////////////////////////////////////// -void CEntityObject::OnMaterialChanged(MaterialChangeFlags change) -{ - if (change & MATERIALCHANGE_SURFACETYPE) - { - m_statObjValidator.Validate(0, GetRenderMaterial()); - } -} - -////////////////////////////////////////////////////////////////////////// -QString CEntityObject::GetTooltip() const -{ - return m_statObjValidator.GetDescription(); -} - ////////////////////////////////////////////////////////////////////////// IOpticsElementBasePtr CEntityObject::GetOpticsElement() { @@ -1979,7 +1947,6 @@ void CEntityObject::SetOpticsName(const QString& opticsFullName) { pLight->SetLensOpticsElement(NULL); } - SetMaterial(NULL); } } diff --git a/Code/Sandbox/Editor/Objects/EntityObject.h b/Code/Sandbox/Editor/Objects/EntityObject.h index 941094c755..a287cd8828 100644 --- a/Code/Sandbox/Editor/Objects/EntityObject.h +++ b/Code/Sandbox/Editor/Objects/EntityObject.h @@ -21,7 +21,6 @@ #include "IMovieSystem.h" #include "IEntityObjectListener.h" -#include "StatObjValidator.h" #include "Gizmo.h" #include "CryListenerSet.h" #include "StatObjBus.h" @@ -108,8 +107,6 @@ public: void SetEntityPropertyFloat(const char* name, float value); void SetEntityPropertyString(const char* name, const QString& value); - virtual QString GetTooltip() const; - virtual int MouseCreateCallback(CViewport* view, EMouseEvent event, QPoint& point, int flags); virtual void OnContextMenu(QMenu* menu); @@ -134,9 +131,6 @@ public: virtual void SetTransformDelegate(ITransformDelegate* pTransformDelegate) override; - virtual CMaterial* GetRenderMaterial() const; - virtual void OnMaterialChanged(MaterialChangeFlags change); - // Set attach flags and target enum EAttachmentType { @@ -405,8 +399,6 @@ protected: static float m_helperScale; - CStatObjValidator m_statObjValidator; - EAttachmentType m_attachmentType; bool m_bEnableReload; diff --git a/Code/Sandbox/Editor/Objects/ObjectLoader.cpp b/Code/Sandbox/Editor/Objects/ObjectLoader.cpp index 746b9e8c73..41f543a5a3 100644 --- a/Code/Sandbox/Editor/Objects/ObjectLoader.cpp +++ b/Code/Sandbox/Editor/Objects/ObjectLoader.cpp @@ -17,7 +17,6 @@ // Editor #include "Util/PakFile.h" -#include "Material/MaterialManager.h" #include "WaitProgress.h" #include "Include/IObjectManager.h" @@ -239,14 +238,6 @@ void CObjectArchive::ResolveObjects() obj.pObject->CreateGameObject(); - CMaterial* pMaterial = obj.pObject->GetRenderMaterial(); - CMaterialManager* pManager = GetIEditor()->GetMaterialManager(); - - if (pMaterial && pMaterial->GetMatInfo() && pManager) - { - pManager->OnRequestMaterial(pMaterial->GetMatInfo()); - } - // unset the current validator object because the wait Step // might generate unrelated errors m_pCurrentErrorReport->SetCurrentValidatorObject(nullptr); diff --git a/Code/Sandbox/Editor/Objects/SelectionGroup.cpp b/Code/Sandbox/Editor/Objects/SelectionGroup.cpp index b883b78e49..08abf8f763 100644 --- a/Code/Sandbox/Editor/Objects/SelectionGroup.cpp +++ b/Code/Sandbox/Editor/Objects/SelectionGroup.cpp @@ -20,7 +20,7 @@ // Editor #include "ViewManager.h" -#include "SurfaceInfoPicker.h" +#include "Include/IObjectManager.h" ////////////////////////////////////////////////////////////////////////// @@ -238,16 +238,6 @@ void CSelectionGroup::Move(const Vec3& offset, EMoveSelectionFlag moveFlag, [[ma } SRayHitInfo pickedInfo; - if (moveFlag == eMS_FollowGeometryPosNorm && bValidFollowGeometryMode) - { - CSurfaceInfoPicker::CExcludedObjects excludeObjects; - for (int i = 0; i < GetFilteredCount(); ++i) - { - excludeObjects.Add(GetFilteredObject(i)); - } - CSurfaceInfoPicker surfacePicker; - bValidFollowGeometryMode = surfacePicker.Pick(point, pickedInfo, &excludeObjects); - } if (moveFlag == eMS_FollowGeometryPosNorm) { diff --git a/Code/Sandbox/Editor/Objects/StatObjValidator.cpp b/Code/Sandbox/Editor/Objects/StatObjValidator.cpp deleted file mode 100644 index 85226fb236..0000000000 --- a/Code/Sandbox/Editor/Objects/StatObjValidator.cpp +++ /dev/null @@ -1,200 +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 "StatObjValidator.h" - -// Editor -#include "Material/Material.h" - - -CStatObjValidator::CStatObjValidator() - : m_isValid(true) -{ -} - -template -bool HasPrefix(const char* name, const char (&prefix)[size]) -{ - return _strnicmp(name, prefix, size - 1) == 0; -} - -struct SMeshMaterialIssue -{ - AZStd::string nodeName; - AZStd::string description; - int subMaterialIndex; - - SMeshMaterialIssue() - : subMaterialIndex(-1) - { - } - - SMeshMaterialIssue(const AZStd::string& name, const AZStd::string& description) - : nodeName(name) - , description(description) - , subMaterialIndex(-1) - { - } -}; - -static void ValidateMeshMaterials(std::vector* issues, IStatObj* pStatObj, CMaterial* pMaterial) -{ - _smart_ptr pIMaterial = 0; - if (pMaterial) - { - if (pMaterial->GetParent()) - { - pIMaterial = pMaterial->GetParent()->GetMatInfo(); - } - else - { - pIMaterial = pMaterial->GetMatInfo(); - } - } - - IIndexedMesh* pIndexedMesh = pStatObj->GetIndexedMesh(true); - if (pIndexedMesh) - { - int breakableSubmeshes = 0; - int nonbreakableSubmeshes = 0; - - int subsetCount = pIndexedMesh->GetSubSetCount(); - for (int i = 0; i < subsetCount; ++i) - { - const SMeshSubset& subset = pIndexedMesh->GetSubSet(i); - if (subset.nNumVerts == 0) - { - continue; - } - - // Check to see if the material uses multiple uv sets and if the vertex format has the same number of texCoord attributes - SShaderItem shaderItem = pIMaterial->GetShaderItem(i); - if (shaderItem.m_pShader) - { - size_t materialUVs = shaderItem.m_pShader->GetNumberOfUVSets(); - size_t meshUVs = subset.vertexFormat.GetAttributeUsageCount(AZ::Vertex::AttributeUsage::TexCoord); - if (materialUVs != meshUVs) - { - const char* meshName = pStatObj->GetRenderMesh() ? pStatObj->GetRenderMesh()->GetSourceName() : "unknown"; - AZStd::string errorMessage; - errorMessage = AZStd::string::format("Material '%s' sub-material %d with %zu uv set(s) was assigned to mesh '%s' with %zu uv set(s). ", pIMaterial->GetName(), i + 1, materialUVs, meshName, meshUVs); - - AZStd::string recommendedAction; - if (materialUVs < meshUVs) - { - recommendedAction = AZStd::string::format("If you do not intend to use %zu uv sets, remove the extra uv set(s) from the source mesh during the import process. Otherwise, consider checking the desired 'Use uv set 2 for...' shader gen params in the material editor.", meshUVs); - } - else - { - recommendedAction = AZStd::string::format("If you intend to use %zu uv sets, include the additional uv set(s) in the source mesh during the import process. Otherwise, consider unchecking the 'Use uv set 2 for...' shader gen params in the material editor.", materialUVs); - } - errorMessage += recommendedAction; - AZ_Warning("Material Editor", false, errorMessage.c_str()); - SMeshMaterialIssue issue(meshName, errorMessage); - issues->push_back(issue); - } - } - - _smart_ptr pSubMaterial = pIMaterial->GetSubMtl(subset.nMatID); - if (!pSubMaterial) - { - continue; - } - - if (size_t(subset.nMatID) > size_t(pMaterial->GetSubMaterialCount())) - { - continue; - } - - if (pSubMaterial->GetSurfaceType()->GetBreakable2DParams()) - { - ++breakableSubmeshes; - } - else - { - ++nonbreakableSubmeshes; - } - } - } - - - int subobjectCount = pStatObj->GetSubObjectCount(); - for (int i = 0; i < subobjectCount; ++i) - { - const IStatObj::SSubObject* subobject = pStatObj->GetSubObject(i); - if (subobject->pStatObj) - { - ValidateMeshMaterials(issues, subobject->pStatObj, pMaterial); - } - } -} - -void CStatObjValidator::Validate(IStatObj* statObj, CMaterial* editorMaterial) -{ - m_description = QString(); - m_isValid = true; - - _smart_ptr pIMaterial = 0; - if (editorMaterial) - { - if (editorMaterial->GetParent()) - { - pIMaterial = editorMaterial->GetParent()->GetMatInfo(); - } - else - { - pIMaterial = editorMaterial->GetMatInfo(); - } - } - - if (statObj && editorMaterial) - { - std::vector issues; - ValidateMeshMaterials(&issues, statObj, editorMaterial); - - if (!issues.empty()) - { - m_isValid = false; - } - - for (size_t i = 0; i < issues.size(); ++i) - { - const SMeshMaterialIssue& issue = issues[i]; - if (!m_description.isEmpty()) - { - m_description += "\n"; - } - if (!issue.nodeName.empty()) - { - m_description += "Node "; - m_description += issue.nodeName.c_str(); - m_description += ":"; - } - if (issue.subMaterialIndex >= 0) - { - m_description += QStringLiteral("SubMaterial %1:").arg(issue.subMaterialIndex + 1); - } - if (!issue.nodeName.empty() || issue.subMaterialIndex >= 0) - { - m_description += "\n "; - } - if (!issue.description.empty()) - { - m_description += issue.description.c_str(); - } - } - } -} - diff --git a/Code/Sandbox/Editor/Objects/StatObjValidator.h b/Code/Sandbox/Editor/Objects/StatObjValidator.h deleted file mode 100644 index 40145e90c5..0000000000 --- a/Code/Sandbox/Editor/Objects/StatObjValidator.h +++ /dev/null @@ -1,32 +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. - -// This class is supposed to validate CGF with assigned material. -// Some of the asset issues may be diagnosed only when SurfaceType is known. - -#pragma once - -class CRYEDIT_API CStatObjValidator -{ -public: - CStatObjValidator(); - - void Validate(IStatObj* statObj, CMaterial* editorMaterial); - bool IsValid() const { return m_isValid; } - - QString GetDescription() const { return m_description; } -private: - bool m_isValid; - QString m_description; -}; - diff --git a/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.cpp b/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.cpp deleted file mode 100644 index cee7f0f716..0000000000 --- a/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.cpp +++ /dev/null @@ -1,213 +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 "AxisHelperExtended.h" - -#include "CryPhysicsDeprecation.h" - -// Editor -#include "Include/IDisplayViewport.h" -#include "SurfaceInfoPicker.h" -#include "Objects/DisplayContext.h" -#include "Objects/SelectionGroup.h" -#include "Util/fastlib.h" - - -////////////////////////////////////////////////////////////////////////// -// Helper Extended Axis object. -////////////////////////////////////////////////////////////////////////// -CAxisHelperExtended::CAxisHelperExtended() - : m_matrix(IDENTITY) - , m_vPos(ZERO) - , m_pCurObject(0) - , m_dwLastUpdateTime(0) - , m_fMaxDist(100.0f) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CAxisHelperExtended::DrawAxes(DisplayContext& dc, const Matrix34& matrix, bool bUsePhysicalProxy) -{ - const DWORD dwUpdateTime = 2000; // 2 sec - CSelectionGroup* pSel = GetIEditor()->GetSelection(); - int numSels = pSel->GetCount(); - - if (numSels == 0) - { - return; - } - - CBaseObject* pCurObject = pSel->GetObject(numSels - 1); // get just last object for simple check - - // Add current selection to the elements to be skipped - CRY_PHYSICS_REPLACEMENT_ASSERT(); - - Vec3 x = Vec3(1, 0, 0); - Vec3 y = Vec3(0, 1, 0); - Vec3 z = Vec3(0, 0, 1); - - Vec3 colR = Vec3(1, 0, 0); - Vec3 colG = Vec3(0, 1, 0); - Vec3 colB = Vec3(0, 0.8f, 1); - - m_vPos = matrix.GetTranslation(); - - Vec3 vDirX = (matrix * x - m_vPos); - Vec3 vDirY = (matrix * y - m_vPos); - Vec3 vDirZ = (matrix * z - m_vPos); - vDirX.Normalize(); - vDirY.Normalize(); - vDirZ.Normalize(); - - if ( - m_pCurObject != pCurObject || - GetTickCount() - m_dwLastUpdateTime > dwUpdateTime || - !Matrix34::IsEquivalent(m_matrix, matrix) - ) - { - Vec3 outTmp; - AABB aabb(m_vPos, m_fMaxDist); - m_objects.clear(); - CBaseObjectsArray allObjects; - GetIEditor()->GetObjectManager()->GetObjects(allObjects); - - for (size_t i = 0, n = allObjects.size(); i < n; ++i) - { - CBaseObject* pObject = allObjects[i]; - if (pObject->IsSelected() || !pObject->GetEngineNode()) - { - continue; - } - - AABB aabbObj; - pObject->GetBoundBox(aabbObj); - - if (!Intersect::Ray_AABB(m_vPos, vDirX, aabbObj, outTmp) - && !Intersect::Ray_AABB(m_vPos, vDirY, aabbObj, outTmp) - && !Intersect::Ray_AABB(m_vPos, vDirZ, aabbObj, outTmp) - && !Intersect::Ray_AABB(m_vPos, -vDirX, aabbObj, outTmp) - && !Intersect::Ray_AABB(m_vPos, -vDirY, aabbObj, outTmp) - && !Intersect::Ray_AABB(m_vPos, -vDirZ, aabbObj, outTmp)) - { - continue; - } - - if (aabb.IsIntersectBox(aabbObj)) - { - m_objects.push_back(pObject); - } - } - m_dwLastUpdateTime = GetTickCount(); - } - m_pCurObject = pCurObject; - m_matrix = matrix; - - DrawAxis(dc, vDirX, z, colR, bUsePhysicalProxy); - DrawAxis(dc, vDirY, z, colG, bUsePhysicalProxy); - DrawAxis(dc, vDirZ, x, colB, bUsePhysicalProxy); - DrawAxis(dc, -vDirX, z, colR, bUsePhysicalProxy); - DrawAxis(dc, -vDirY, z, colG, bUsePhysicalProxy); - DrawAxis(dc, -vDirZ, x, colB, bUsePhysicalProxy); -} - - -////////////////////////////////////////////////////////////////////////// -void CAxisHelperExtended::DrawAxis(DisplayContext& dc, const Vec3& vDir, const Vec3& vUpAxis, const Vec3& col, bool bUsePhysicalProxy) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::Editor); - - const float fBallSize = 0.005f; - const float fTextSize = 1.4f; - - float fDist = m_fMaxDist + 1.0f; - size_t objectsSize = m_objects.size(); - for (size_t i = 0; i < objectsSize; ++i) - { - CBaseObject* pObject = m_objects[i]; - if (pObject->CheckFlags(OBJFLAG_DELETED)) - { - continue; - } - - SRayHitInfo hitInfo; - if (pObject->IntersectRayMesh(m_vPos, vDir, hitInfo)) - { - Vec3 newP = pObject->GetWorldTM().TransformPoint(hitInfo.vHitPos); - float fNewDist = (newP - m_vPos).GetLength(); - if (fDist > fNewDist) - { - fDist = fNewDist; - } - } - } - - if (bUsePhysicalProxy) - { - CRY_PHYSICS_REPLACEMENT_ASSERT(); - } - else - { - CSurfaceInfoPicker picker; - m_objectsForPicker.assign(m_objects.begin(), m_objects.end()); - picker.SetObjects(&m_objectsForPicker); - SRayHitInfo hitInfo; - if (picker.Pick(m_vPos, fDist * vDir, hitInfo, NULL, CSurfaceInfoPicker::ePOG_All)) - { - fDist = hitInfo.fDistance; - } - picker.SetObjects(0); - } - - if (fDist < m_fMaxDist) - { - Vec3 p = m_vPos + vDir * fDist; - - dc.SetColor(col); - dc.DrawLine(m_vPos, p); - float fScreenScale = dc.view->GetScreenScaleFactor(p); - dc.DrawBall(p, fBallSize * fScreenScale); - QString label; - label = QString::number(fDist, 'f', 2); - dc.DrawTextOn2DBox((p + m_vPos) * 0.5f, label.toUtf8().data(), fTextSize, col, ColorF(0.0f, 0.0f, 0.0f, 0.7f)); - - Vec3 vUp = (m_matrix * vUpAxis - m_vPos); - vUp.Normalize(); - - Vec3 u = vUp; - Vec3 v = vDir ^ vUp; - float fPlaneSize = fDist / 4.0f; - float alphaMax = 1.0f, alphaMin = 0.0f; - ColorF colAlphaMin = ColorF(col.x, col.y, col.z, alphaMin); - - float fStepSize = dc.view->GetGridStep(); - const int MIN_STEP_COUNT = 5; - const int MAX_STEP_COUNT = 20; - int nSteps = std::min(std::max(FloatToIntRet(fPlaneSize / fStepSize), MIN_STEP_COUNT), MAX_STEP_COUNT); - float fGridSize = nSteps * fStepSize; - - for (int i = -nSteps; i <= nSteps; ++i) - { - Vec3 stepV = v * (fStepSize * i); - Vec3 stepU = u * (fStepSize * i); - ColorF colCurAlpha = ColorF(col.x, col.y, col.z, alphaMax - fabsf(float(i) / float(nSteps)) * (alphaMax - alphaMin)); - // Draw u lines. - dc.DrawLine(p + stepV, p + u * fGridSize + stepV, colCurAlpha, colAlphaMin); - dc.DrawLine(p + stepV, p - u * fGridSize + stepV, colCurAlpha, colAlphaMin); - // Draw v lines. - dc.DrawLine(p + stepU, p + v * fGridSize + stepU, colCurAlpha, colAlphaMin); - dc.DrawLine(p + stepU, p - v * fGridSize + stepU, colCurAlpha, colAlphaMin); - } - } -} diff --git a/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.h b/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.h deleted file mode 100644 index 42a1c66b9c..0000000000 --- a/Code/Sandbox/Editor/RenderHelpers/AxisHelperExtended.h +++ /dev/null @@ -1,44 +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_RENDERHELPERS_AXISHELPEREXTENDED_H -#define CRYINCLUDE_EDITOR_RENDERHELPERS_AXISHELPEREXTENDED_H -#pragma once - -#include "Objects/BaseObject.h" -#include "Include/IObjectManager.h" - -struct DisplayContext; -struct HitContext; - -class CAxisHelperExtended -{ -public: - CAxisHelperExtended(); - void DrawAxes(DisplayContext& dc, const Matrix34& matrix, bool bUsePhysicalProxy); - -private: - void DrawAxis(DisplayContext& dc, const Vec3& vDirAxis, const Vec3& vUpAxis, const Vec3& col, bool bUsePhysicalProxy); - -private: - Matrix34 m_matrix; - Vec3 m_vPos; - std::vector m_objects; - CBaseObjectsArray m_objectsForPicker; - CBaseObject* m_pCurObject; - DWORD m_dwLastUpdateTime; - - float m_fMaxDist; -}; - -#endif // CRYINCLUDE_EDITOR_RENDERHELPERS_AXISHELPEREXTENDED_H diff --git a/Code/Sandbox/Editor/Resource.h b/Code/Sandbox/Editor/Resource.h index 78a9855d71..51f9b1f3e9 100644 --- a/Code/Sandbox/Editor/Resource.h +++ b/Code/Sandbox/Editor/Resource.h @@ -95,9 +95,6 @@ #define ID_CHANGEMOVESPEED_INCREASE 32928 #define ID_CHANGEMOVESPEED_DECREASE 32929 #define ID_CHANGEMOVESPEED_CHANGESTEP 32930 -#define ID_MATERIAL_ASSIGNCURRENT 32933 -#define ID_MATERIAL_RESETTODEFAULT 32934 -#define ID_MATERIAL_GETMATERIAL 32935 #define ID_PHYSICS_GETPHYSICSSTATE 32937 #define ID_PHYSICS_RESETPHYSICSSTATE 32938 #define ID_GAME_SYNCPLAYER 32941 diff --git a/Code/Sandbox/Editor/SurfaceInfoPicker.cpp b/Code/Sandbox/Editor/SurfaceInfoPicker.cpp deleted file mode 100644 index 5ef20dcec0..0000000000 --- a/Code/Sandbox/Editor/SurfaceInfoPicker.cpp +++ /dev/null @@ -1,535 +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 "SurfaceInfoPicker.h" - -// AzToolsFramework -#include - -// Editor -#include "Material/MaterialManager.h" -#include "Objects/EntityObject.h" -#include "Viewport.h" -#include "QtViewPane.h" - -// ComponentEntityEditorPlugin -#include "Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h" - -static const float kEnoughFarDistance(5000.0f); - -CSurfaceInfoPicker::CSurfaceInfoPicker() - : m_pObjects(NULL) - , m_pSetObjects(NULL) - , m_PickOption(0) -{ - m_pActiveView = GetIEditor()->GetActiveView(); -} - -bool CSurfaceInfoPicker::PickByAABB(const QPoint& point, [[maybe_unused]] int nFlag, IDisplayViewport* pView, CExcludedObjects* pExcludedObjects, std::vector* pOutObjects) -{ - GetIEditor()->GetObjectManager()->GetObjects(m_objects); - - Vec3 vWorldRaySrc, vWorldRayDir; - m_pActiveView->ViewToWorldRay(point, vWorldRaySrc, vWorldRayDir); - vWorldRaySrc = vWorldRaySrc + vWorldRayDir * 0.1f; - vWorldRayDir = vWorldRayDir * kEnoughFarDistance; - - bool bPicked = false; - - for (int i = 0, iCount(m_objects.size()); i < iCount; ++i) - { - if (pExcludedObjects && pExcludedObjects->Contains(m_objects[i])) - { - continue; - } - - AABB worldObjAABB; - m_objects[i]->GetBoundBox(worldObjAABB); - - if (pView) - { - float fScreenFactor = pView->GetScreenScaleFactor(m_objects[i]->GetPos()); - worldObjAABB.Expand(0.01f * Vec3(fScreenFactor, fScreenFactor, fScreenFactor)); - } - - Vec3 vHitPos; - if (Intersect::Ray_AABB(vWorldRaySrc, vWorldRayDir, worldObjAABB, vHitPos)) - { - if ((vHitPos - vWorldRaySrc).GetNormalized().Dot(vWorldRayDir) > 0 || worldObjAABB.IsContainPoint(vHitPos)) - { - if (pOutObjects) - { - pOutObjects->push_back(m_objects[i]); - } - bPicked = true; - } - } - } - - return bPicked; -} - -bool CSurfaceInfoPicker::PickImpl(const QPoint& point, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects, - int nFlag) -{ - Vec3 vWorldRaySrc; - Vec3 vWorldRayDir; - if (!m_pActiveView) - { - m_pActiveView = GetIEditor()->GetActiveView(); - } - m_pActiveView->ViewToWorldRay(point, vWorldRaySrc, vWorldRayDir); - vWorldRaySrc = vWorldRaySrc + vWorldRayDir * 0.1f; - vWorldRayDir = vWorldRayDir * kEnoughFarDistance; - - return PickImpl(vWorldRaySrc, vWorldRayDir, ppOutLastMaterial, outHitInfo, pExcludedObjects, nFlag); -} - -bool CSurfaceInfoPicker::PickImpl(const Vec3& vWorldRaySrc, const Vec3& vWorldRayDir, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects, - int nFlag) -{ - memset(&outHitInfo, 0, sizeof(outHitInfo)); - outHitInfo.fDistance = kEnoughFarDistance; - - if (m_pSetObjects) - { - m_pObjects = m_pSetObjects; - } - else - { - GetIEditor()->GetObjectManager()->GetObjects(m_objects); - m_pObjects = &m_objects; - } - - if (pExcludedObjects) - { - m_ExcludedObjects = *pExcludedObjects; - } - else - { - m_ExcludedObjects.Clear(); - } - - m_pPickedObject = NULL; - - if (nFlag & ePOG_Entity) - { - FindNearestInfoFromEntities(vWorldRaySrc, vWorldRayDir, ppOutLastMaterial, outHitInfo); - } - - if (!m_pSetObjects) - { - m_objects.clear(); - } - - m_ExcludedObjects.Clear(); - - return outHitInfo.fDistance < kEnoughFarDistance; -} - -void CSurfaceInfoPicker::FindNearestInfoFromEntities( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - _smart_ptr* pOutLastMaterial, - SRayHitInfo& outHitInfo) const -{ - for (size_t i = 0; i < m_pObjects->size(); ++i) - { - CBaseObject* object((*m_pObjects)[i]); - - if (object == nullptr - || !qobject_cast(object) - || object->IsHidden() - || IsFrozen(object) - || m_ExcludedObjects.Contains(object) - ) - { - continue; - } - - CEntityObject* entityObject = static_cast(object); - - // If a legacy entity doesn't have a material override, we'll get the default material for that statObj - _smart_ptr statObjDefaultMaterial = nullptr; - // And in some cases the material we want does comes from RayIntersection(), and we will skip AssignObjectMaterial(). - _smart_ptr pickedMaterial = nullptr; - - bool hit = false; - - // entityObject is a component entity... - if (entityObject->GetType() == OBJTYPE_AZENTITY) - { - AZ::EntityId id; - AzToolsFramework::ComponentEntityObjectRequestBus::EventResult(id, entityObject, &AzToolsFramework::ComponentEntityObjectRequestBus::Events::GetAssociatedEntityId); - - // If the entity has an ActorComponent or another component that overrides RenderNodeRequestBus, it will hit here - if (!hit) - { - // There might be multiple components with render nodes on the same entity - // This will get the highest priority one, as determined by RenderNodeRequests::GetRenderNodeRequestBusOrder - IRenderNode* renderNode = entityObject->GetEngineNode(); - - // If the renderNode exists and is physicalized, it will hit here - hit = RayIntersection_IRenderNode(vWorldRaySrc, vWorldRayDir, renderNode, &pickedMaterial, object->GetWorldTM(), outHitInfo); - if (!hit) - { - // If the renderNode is not physicalized, such as an actor component, but still exists and has a valid material we might want to pick - if (renderNode && renderNode->GetMaterial()) - { - // Do a hit test with anything in this entity that has overridden EditorComponentSelectionRequestsBus - CComponentEntityObject* componentEntityObject = static_cast(entityObject); - HitContext hc; - hc.raySrc = vWorldRaySrc; - hc.rayDir = vWorldRayDir; - bool intersects = componentEntityObject->HitTest(hc); - - if (intersects) - { - // If the distance is closer than the nearest distance so far - if (hc.dist < outHitInfo.fDistance) - { - hit = true; - outHitInfo.vHitPos = hc.raySrc + hc.rayDir * hc.dist; - outHitInfo.fDistance = hc.dist; - // We don't get material/sub-material information back from HitTest, so just use the material from the render node - pickedMaterial = renderNode->GetMaterial(); - outHitInfo.nHitMatID = 0; - // We don't get normal information back from HitTest, so just orient the selection disk towards the camera - outHitInfo.vHitNormal = vWorldRayDir.normalized(); - } - } - } - } - } - } - - if (hit) - { - if(pickedMaterial) - { - AssignMaterial(pickedMaterial, outHitInfo, pOutLastMaterial); - } - else - { - if (object->GetMaterial()) - { - // If the entity has a material override, assign the object material - AssignObjectMaterial(object, outHitInfo, pOutLastMaterial); - } - else - { - // Otherwise assign the default material for that object - AssignMaterial(statObjDefaultMaterial, outHitInfo, pOutLastMaterial); - } - } - - m_pPickedObject = object; - } - } -} - -bool CSurfaceInfoPicker::RayIntersection_CBaseObject( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - CBaseObject* pBaseObject, - _smart_ptr* pOutLastMaterial, - SRayHitInfo& outHitInfo) -{ - if (pBaseObject == NULL) - { - return false; - } - IRenderNode* pRenderNode(pBaseObject->GetEngineNode()); - if (pRenderNode == NULL) - { - return false; - } - IStatObj* pStatObj(pRenderNode->GetEntityStatObj()); - if (pStatObj == NULL) - { - return false; - } - return RayIntersection(vWorldRaySrc, vWorldRayDir, pRenderNode, pStatObj, pBaseObject->GetWorldTM(), outHitInfo, pOutLastMaterial); -} - -bool CSurfaceInfoPicker::RayIntersection( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IRenderNode* pRenderNode, - IStatObj* pStatObj, - const Matrix34A& WorldTM, - SRayHitInfo& outHitInfo, - _smart_ptr* ppOutLastMaterial) -{ - SRayHitInfo hitInfo; - bool bRayIntersection = false; - _smart_ptr pMaterial(NULL); - - bRayIntersection = RayIntersection_IStatObj(vWorldRaySrc, vWorldRayDir, pStatObj, &pMaterial, WorldTM, hitInfo); - if (!bRayIntersection) - { - bRayIntersection = RayIntersection_IRenderNode(vWorldRaySrc, vWorldRayDir, pRenderNode, &pMaterial, WorldTM, hitInfo); - } - - if (bRayIntersection) - { - hitInfo.fDistance = vWorldRaySrc.GetDistance(hitInfo.vHitPos); - if (hitInfo.fDistance < outHitInfo.fDistance) - { - if (ppOutLastMaterial) - { - *ppOutLastMaterial = pMaterial; - } - memcpy(&outHitInfo, &hitInfo, sizeof(SRayHitInfo)); - outHitInfo.vHitNormal.Normalize(); - return true; - } - } - return false; -} - -bool CSurfaceInfoPicker::RayIntersection_IStatObj( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IStatObj* pStatObj, - _smart_ptr* ppOutLastMaterial, - const Matrix34A& worldTM, - SRayHitInfo& outHitInfo) -{ - if (pStatObj == NULL) - { - return false; - } - - Vec3 localRaySrc; - Vec3 localRayDir; - if (!RayWorldToLocal(worldTM, vWorldRaySrc, vWorldRayDir, localRaySrc, localRayDir)) - { - return false; - } - - // the outHitInfo contains information about the previous closest hit and should not be cleared / replaced unless you have a better hit! - // all of the intersection functions called (such as statobj's RayIntersection) only modify the hit info if it actually hits it closer than the current distance of the last hit. - - outHitInfo.inReferencePoint = localRaySrc; - outHitInfo.inRay = Ray(localRaySrc, localRayDir); - outHitInfo.bInFirstHit = false; - outHitInfo.bUseCache = false; - - _smart_ptr hitMaterial = nullptr; - - Vec3 hitPosOnAABB; - if (Intersect::Ray_AABB(outHitInfo.inRay, pStatObj->GetAABB(), hitPosOnAABB) == 0x00) - { - return false; - } - - if (pStatObj->RayIntersection(outHitInfo)) - { - if (outHitInfo.fDistance < 0) - { - return false; - } - outHitInfo.vHitPos = worldTM.TransformPoint(outHitInfo.vHitPos); - outHitInfo.vHitNormal = worldTM.GetTransposed().GetInverted().TransformVector(outHitInfo.vHitNormal); - - // we need to set nHitSurfaceID anyway - so we need to do this regardless of whether the caller - // has asked for detailed material info by passing in a non-null ppOutLastMaterial - hitMaterial = pStatObj->GetMaterial(); - - if (hitMaterial) - { - if (outHitInfo.nHitMatID >= 0) - { - if (hitMaterial->GetSubMtlCount() > 0 && outHitInfo.nHitMatID < hitMaterial->GetSubMtlCount()) - { - _smart_ptr subMaterial = hitMaterial->GetSubMtl(outHitInfo.nHitMatID); - if (subMaterial) - { - hitMaterial = subMaterial; - } - } - } - outHitInfo.nHitSurfaceID = hitMaterial->GetSurfaceTypeId(); - } - - if ((ppOutLastMaterial) && (hitMaterial)) - { - *ppOutLastMaterial = hitMaterial; - } - - return true; - } - - return outHitInfo.fDistance < kEnoughFarDistance; -} - -#if defined(USE_GEOM_CACHES) -bool CSurfaceInfoPicker::RayIntersection_IGeomCacheRenderNode( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IGeomCacheRenderNode* pGeomCacheRenderNode, - _smart_ptr* ppOutLastMaterial, - [[maybe_unused]] const Matrix34A& worldTM, - SRayHitInfo& outHitInfo) -{ - if (!pGeomCacheRenderNode) - { - return false; - } - - SRayHitInfo newHitInfo = outHitInfo; - newHitInfo.inReferencePoint = vWorldRaySrc; - newHitInfo.inRay = Ray(vWorldRaySrc, vWorldRayDir); - newHitInfo.bInFirstHit = false; - newHitInfo.bUseCache = false; - - if (pGeomCacheRenderNode->RayIntersection(newHitInfo)) - { - if (newHitInfo.fDistance < 0 || newHitInfo.fDistance > kEnoughFarDistance || (outHitInfo.fDistance != 0 && newHitInfo.fDistance > outHitInfo.fDistance)) - { - return false; - } - - // Only override outHitInfo if the new hit is closer than the original hit - outHitInfo = newHitInfo; - if (ppOutLastMaterial) - { - _smart_ptr pMaterial = pGeomCacheRenderNode->GetMaterial(); - if (pMaterial) - { - *ppOutLastMaterial = pMaterial; - if (outHitInfo.nHitMatID >= 0) - { - if (pMaterial->GetSubMtlCount() > 0 && outHitInfo.nHitMatID < pMaterial->GetSubMtlCount()) - { - *ppOutLastMaterial = pMaterial->GetSubMtl(outHitInfo.nHitMatID); - } - } - } - } - return true; - } - - return false; -} -#endif - -bool CSurfaceInfoPicker::RayIntersection_IRenderNode( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IRenderNode* pRenderNode, - _smart_ptr* pOutLastMaterial, - [[maybe_unused]] const Matrix34A& WorldTM, - SRayHitInfo& outHitInfo) -{ - if (pRenderNode == NULL) - { - return false; - } - - AZ_UNUSED(vWorldRaySrc) - AZ_UNUSED(vWorldRayDir) - AZ_UNUSED(pRenderNode) - AZ_UNUSED(pOutLastMaterial) - AZ_UNUSED(WorldTM) - AZ_UNUSED(outHitInfo) - return false; -} - -bool CSurfaceInfoPicker::RayWorldToLocal( - const Matrix34A& WorldTM, - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - Vec3& outRaySrc, - Vec3& outRayDir) -{ - if (!WorldTM.IsValid()) - { - return false; - } - Matrix34A invertedM(WorldTM.GetInverted()); - if (!invertedM.IsValid()) - { - return false; - } - outRaySrc = invertedM.TransformPoint(vWorldRaySrc); - outRayDir = invertedM.TransformVector(vWorldRayDir).GetNormalized(); - return true; -} - -bool CSurfaceInfoPicker::IsMaterialValid(CMaterial* pMaterial) -{ - if (pMaterial == NULL) - { - return false; - } - return !(pMaterial->GetMatInfo()->GetFlags() & MTL_FLAG_NODRAW); -} - -void CSurfaceInfoPicker::AssignObjectMaterial(CBaseObject* pObject, const SRayHitInfo& outHitInfo, _smart_ptr* pOutMaterial) -{ - CMaterial* material = pObject->GetMaterial(); - if (material) - { - if (material->GetMatInfo()) - { - if (pOutMaterial) - { - *pOutMaterial = material->GetMatInfo(); - if (*pOutMaterial) - { - if (outHitInfo.nHitMatID >= 0 && (*pOutMaterial)->GetSubMtlCount() > 0 && outHitInfo.nHitMatID < (*pOutMaterial)->GetSubMtlCount()) - { - *pOutMaterial = (*pOutMaterial)->GetSubMtl(outHitInfo.nHitMatID); - } - } - } - } - } -} - -void CSurfaceInfoPicker::AssignMaterial(_smart_ptr pMaterial, const SRayHitInfo& outHitInfo, _smart_ptr* pOutMaterial) -{ - if (pOutMaterial) - { - *pOutMaterial = pMaterial; - if (*pOutMaterial) - { - if (outHitInfo.nHitMatID >= 0 && (*pOutMaterial)->GetSubMtlCount() > 0 && outHitInfo.nHitMatID < (*pOutMaterial)->GetSubMtlCount()) - { - *pOutMaterial = (*pOutMaterial)->GetSubMtl(outHitInfo.nHitMatID); - } - } - } -} - -void CSurfaceInfoPicker::SetActiveView(IDisplayViewport* view) -{ - if (view) - { - m_pActiveView = view; - } - else - { - m_pActiveView = GetIEditor()->GetActiveView(); - } -} diff --git a/Code/Sandbox/Editor/SurfaceInfoPicker.h b/Code/Sandbox/Editor/SurfaceInfoPicker.h deleted file mode 100644 index 110408d558..0000000000 --- a/Code/Sandbox/Editor/SurfaceInfoPicker.h +++ /dev/null @@ -1,220 +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_SURFACEINFOPICKER_H -#define CRYINCLUDE_EDITOR_SURFACEINFOPICKER_H - -#pragma once - -#include "Include/IObjectManager.h" -#include "Objects/BaseObject.h" - -class CKDTree; -struct IDisplayViewport; - -////////////////////////////////////////////////////////////////////////// -class SANDBOX_API CSurfaceInfoPicker -{ -public: - - CSurfaceInfoPicker(); - - class CExcludedObjects - { - public: - - CExcludedObjects(){} - ~CExcludedObjects(){} - CExcludedObjects(const CExcludedObjects& excluded) - { - objects = excluded.objects; - } - - void Add(CBaseObject* pObject) - { - objects.insert(pObject); - } - - void Clear() - { - objects.clear(); - } - - bool Contains(CBaseObject* pObject) const - { - return objects.find(pObject) != objects.end(); - } - - private: - std::set objects; - }; - - enum EPickedObjectGroup - { - ePOG_Entity = BIT(1), - ePOG_All = ePOG_Entity, - }; - - enum EPickOption - { - ePickOption_IncludeFrozenObject = BIT(0), - }; - - void SetPickOptionFlag(int nFlag) { m_PickOption = nFlag; } - -public: - - bool Pick(const Vec3& vWorldRaySrc, const Vec3& vWorldRayDir, - _smart_ptr& ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All) - { - return PickImpl(vWorldRaySrc, vWorldRayDir, &ppOutLastMaterial, outHitInfo, pExcludedObjects, nFlag); - } - - bool Pick(const Vec3& vWorldRaySrc, const Vec3& vWorldRayDir, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All) - { - return PickImpl(vWorldRaySrc, vWorldRayDir, NULL, outHitInfo, pExcludedObjects, nFlag); - } - - bool Pick(const QPoint& point, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All) - { - return PickImpl(point, NULL, outHitInfo, pExcludedObjects, nFlag); - } - - bool Pick(const QPoint& point, - _smart_ptr& ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All) - { - return PickImpl(point, &ppOutLastMaterial, outHitInfo, pExcludedObjects, nFlag); - } - - bool PickByAABB(const QPoint& point, int nFlag = ePOG_All, IDisplayViewport* pView = NULL, CExcludedObjects* pExcludedObjects = NULL, std::vector* pOutObjects = NULL); - - void SetObjects(CBaseObjectsArray* pSetObjects) { m_pSetObjects = pSetObjects; } - - CBaseObjectPtr GetPickedObject() - { - return m_pPickedObject; - } - - void SetActiveView(IDisplayViewport* view); - -public: - - static bool RayWorldToLocal( - const Matrix34A& WorldTM, - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - Vec3& outRaySrc, - Vec3& outRayDir); - -private: - - bool IsFrozen(CBaseObject* pBaseObject) const - { - return !(m_PickOption & ePickOption_IncludeFrozenObject) && pBaseObject->IsFrozen(); - } - - bool PickImpl(const QPoint& point, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All); - - bool PickImpl(const Vec3& vWorldRaySrc, const Vec3& vWorldRayDir, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo, - CExcludedObjects* pExcludedObjects = NULL, - int nFlag = ePOG_All); - - void FindNearestInfoFromEntities( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo) const; - - /// Detect ray intersection with a IRenderNode or IStatObj. - /// But only if the intersection is closer than the one already in outHitInfo. - static bool RayIntersection( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IRenderNode* pRenderNode, - IStatObj* pStatObj, - const Matrix34A& WorldTM, - SRayHitInfo& outHitInfo, - _smart_ptr* ppOutLastMaterial); - - /// Detect ray intersection with a IStatObj - static bool RayIntersection_IStatObj( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IStatObj* pStatObj, - _smart_ptr* ppOutLastMaterial, - const Matrix34A& WorldTM, - SRayHitInfo& outHitInfo); - - /// Detect ray intersection with a IGeomCacheRenderNode - static bool RayIntersection_IGeomCacheRenderNode( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IGeomCacheRenderNode* pGeomCacheRenderNode, - _smart_ptr* ppOutLastMaterial, - const Matrix34A& worldTM, - SRayHitInfo& outHitInfo); - - /// Detect ray intersection with a IRenderNode - static bool RayIntersection_IRenderNode( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - IRenderNode* pRenderNode, - _smart_ptr* ppOutLastMaterial, - const Matrix34A& WorldTM, - SRayHitInfo& outHitInfo); - - /// Detect ray intersection with a CBaseObject - static bool RayIntersection_CBaseObject( - const Vec3& vWorldRaySrc, - const Vec3& vWorldRayDir, - CBaseObject* pBaseObject, - _smart_ptr* ppOutLastMaterial, - SRayHitInfo& outHitInfo); - - static void AssignObjectMaterial(CBaseObject* pObject, const SRayHitInfo& outHitInfo, _smart_ptr* pOutMaterial); - static void AssignMaterial(_smart_ptr pObject, const SRayHitInfo& outHitInfo, _smart_ptr* pOutMaterial); - static bool IsMaterialValid(CMaterial* pMaterial); - -private: - - int m_PickOption; - - AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING - CBaseObjectsArray* m_pObjects; - CBaseObjectsArray* m_pSetObjects; - CBaseObjectsArray m_objects; - IDisplayViewport* m_pActiveView; - CExcludedObjects m_ExcludedObjects; - mutable CBaseObjectPtr m_pPickedObject; - AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING -}; - -#endif // CRYINCLUDE_EDITOR_SURFACEINFOPICKER_H diff --git a/Code/Sandbox/Editor/SurfaceTypeValidator.cpp b/Code/Sandbox/Editor/SurfaceTypeValidator.cpp index 68bbdcf3bb..9aec070912 100644 --- a/Code/Sandbox/Editor/SurfaceTypeValidator.cpp +++ b/Code/Sandbox/Editor/SurfaceTypeValidator.cpp @@ -16,7 +16,6 @@ #include "SurfaceTypeValidator.h" // Editor -#include "Material/Material.h" #include "Include/IObjectManager.h" #include "Objects/BaseObject.h" #include "ErrorReport.h" diff --git a/Code/Sandbox/Editor/TrackView/TrackViewSequenceManager.cpp b/Code/Sandbox/Editor/TrackView/TrackViewSequenceManager.cpp index 12f38c920a..0ba7c5b325 100644 --- a/Code/Sandbox/Editor/TrackView/TrackViewSequenceManager.cpp +++ b/Code/Sandbox/Editor/TrackView/TrackViewSequenceManager.cpp @@ -27,7 +27,6 @@ #include "AnimationContext.h" #include "GameEngine.h" #include "Include/IObjectManager.h" -#include "Material/MaterialManager.h" #include "Objects/ObjectManager.h" @@ -35,7 +34,6 @@ CTrackViewSequenceManager::CTrackViewSequenceManager() { GetIEditor()->RegisterNotifyListener(this); - GetIEditor()->GetMaterialManager()->AddListener(this); AZ::EntitySystemBus::Handler::BusConnect(); } @@ -45,7 +43,6 @@ CTrackViewSequenceManager::~CTrackViewSequenceManager() { AZ::EntitySystemBus::Handler::BusDisconnect(); - GetIEditor()->GetMaterialManager()->RemoveListener(this); GetIEditor()->UnregisterNotifyListener(this); } diff --git a/Code/Sandbox/Editor/Util/Variable.h b/Code/Sandbox/Editor/Util/Variable.h index 20c18d4409..d00ef6103a 100644 --- a/Code/Sandbox/Editor/Util/Variable.h +++ b/Code/Sandbox/Editor/Util/Variable.h @@ -152,7 +152,7 @@ struct IVariable DT_LOCAL_STRING, DT_EQUIP, DT_REVERBPRESET, - DT_MATERIAL, + DT_DEPRECATED0, // formerly DT_MATERIAL DT_MATERIALLOOKUP, DT_EXTARRAY, // Extendable Array DT_SEQUENCE, // Movie Sequence (DEPRECATED, use DT_SEQUENCE_ID, instead.) diff --git a/Code/Sandbox/Editor/Util/VariablePropertyType.cpp b/Code/Sandbox/Editor/Util/VariablePropertyType.cpp index c80461182d..c7fd3d9de2 100644 --- a/Code/Sandbox/Editor/Util/VariablePropertyType.cpp +++ b/Code/Sandbox/Editor/Util/VariablePropertyType.cpp @@ -49,7 +49,7 @@ namespace Prop { IVariable::DT_SIMPLE, "Selection", ePropertySelection, -1 }, { IVariable::DT_SIMPLE, "List", ePropertyList, -1 }, { IVariable::DT_SHADER, "Shader", ePropertyShader, 9 }, - { IVariable::DT_MATERIAL, "Material", ePropertyMaterial, 14 }, + { IVariable::DT_DEPRECATED0, "DEPRECATED", ePropertyDeprecated2, -1 }, { IVariable::DT_EQUIP, "Equip", ePropertyEquip, 11 }, { IVariable::DT_REVERBPRESET, "ReverbPreset", ePropertyReverbPreset, 11 }, { IVariable::DT_LOCAL_STRING, "LocalString", ePropertyLocalString, 3 }, diff --git a/Code/Sandbox/Editor/Util/VariablePropertyType.h b/Code/Sandbox/Editor/Util/VariablePropertyType.h index 76379c1bc0..130148c903 100644 --- a/Code/Sandbox/Editor/Util/VariablePropertyType.h +++ b/Code/Sandbox/Editor/Util/VariablePropertyType.h @@ -39,7 +39,7 @@ enum PropertyType ePropertySelection, ePropertyList, ePropertyShader, - ePropertyMaterial, + ePropertyDeprecated2, // formerly ePropertyMaterial ePropertyEquip, ePropertyReverbPreset, ePropertyLocalString, diff --git a/Code/Sandbox/Editor/Util/VariableTypeInfo.cpp b/Code/Sandbox/Editor/Util/VariableTypeInfo.cpp index 61cdac53c6..206131e5a9 100644 --- a/Code/Sandbox/Editor/Util/VariableTypeInfo.cpp +++ b/Code/Sandbox/Editor/Util/VariableTypeInfo.cpp @@ -112,10 +112,6 @@ void CVariableTypeInfo::SetTypes(CTypeInfo const& TypeInfo, EType eType) { SetDataType(DT_TEXTURE); } - else if (m_name == "Material") - { - SetDataType(DT_MATERIAL); - } else if (m_name == "Geometry") { SetDataType(DT_OBJECT); diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index e6337796d6..a0c22c9a14 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -309,15 +309,6 @@ set(FILES Util/AffineParts.cpp Objects/BaseObject.cpp Objects/BaseObject.h - Material/Material.cpp - Material/Material.h - Material/MaterialHelpers.cpp - Material/MaterialHelpers.h - Material/MaterialDialog.qrc - Material/MaterialPreviewModelView.cpp - Material/MaterialPreviewModelView.h - Material/PreviewModelView.cpp - Material/PreviewModelView.h Alembic/AlembicCompileDialog.cpp Alembic/AlembicCompileDialog.h Alembic/AlembicCompileDialog.ui @@ -553,7 +544,6 @@ set(FILES IObservable.h IPostRenderer.h LightmapCompiler/SimpleTriangleRasterizer.h - SurfaceInfoPicker.h ToolBox.h TrackViewNewSequenceDialog.h UndoConfigSpec.h @@ -570,25 +560,6 @@ set(FILES LevelIndependentFileMan.h LogFileImpl.cpp LogFileImpl.h - MatEditPreviewDlg.cpp - MatEditPreviewDlg.h - Material/MaterialBrowser.cpp - Material/MaterialBrowser.h - Material/MaterialBrowser.ui - Material/MaterialBrowserSearchFilters.cpp - Material/MaterialBrowserSearchFilters.h - Material/MaterialBrowserFilterModel.cpp - Material/MaterialBrowserFilterModel.h - Material/MaterialImageListCtrl.cpp - Material/MaterialImageListCtrl.h - Material/MaterialLibrary.cpp - Material/MaterialLibrary.h - Material/MaterialManager.cpp - Material/MaterialManager.h - MaterialSender.h - MaterialSender.cpp - Material/MaterialPythonFuncs.h - Material/MaterialPythonFuncs.cpp Mission.cpp Mission.h Objects/ClassDesc.cpp @@ -596,8 +567,6 @@ set(FILES Objects/IEntityObjectListener.h Objects/SelectionGroup.cpp Objects/SelectionGroup.h - Objects/StatObjValidator.cpp - Objects/StatObjValidator.h Objects/SubObjSelection.cpp Objects/SubObjSelection.h Objects/ObjectLoader.cpp @@ -631,9 +600,7 @@ set(FILES QtUI/WaitCursor.h QtUI/WaitCursor.cpp RenderHelpers/AxisHelper.cpp - RenderHelpers/AxisHelperExtended.cpp RenderHelpers/AxisHelper.h - RenderHelpers/AxisHelperExtended.h Serialization.h Serialization/VariableOArchive.cpp Serialization/VariableOArchive.h @@ -687,7 +654,6 @@ set(FILES LightmapCompiler/SimpleTriangleRasterizer.cpp ResourceSelectorHost.cpp ResourceSelectorHost.h - SurfaceInfoPicker.cpp ThumbnailGenerator.cpp ThumbnailGenerator.h ToolBox.cpp diff --git a/Code/Sandbox/Editor/editor_lib_test_files.cmake b/Code/Sandbox/Editor/editor_lib_test_files.cmake index f537169136..9eca3c56ae 100644 --- a/Code/Sandbox/Editor/editor_lib_test_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_test_files.cmake @@ -18,7 +18,6 @@ set(FILES Lib/Tests/test_EditorUtils.cpp Lib/Tests/test_Main.cpp Lib/Tests/test_MainWindowPythonBindings.cpp - Lib/Tests/test_MaterialPythonFuncs.cpp Lib/Tests/test_ObjectManagerPythonBindings.cpp Lib/Tests/test_TrackViewPythonBindings.cpp Lib/Tests/test_ViewPanePythonBindings.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp index 8f695c39ab..692bb92bf7 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.cpp @@ -46,9 +46,7 @@ #include #include -#include #include -#include #include #include #include @@ -1096,56 +1094,3 @@ void CComponentEntityObject::DrawAccent(DisplayContext& dc) dc.DrawWireBox(box.min, box.max); } } - -void CComponentEntityObject::SetMaterial(CMaterial* material) -{ - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, m_entityId); - if (entity) - { - if (material) - { - EBUS_EVENT_ID(m_entityId, LmbrCentral::MaterialOwnerRequestBus, SetMaterial, material->GetMatInfo()); - } - else - { - EBUS_EVENT_ID(m_entityId, LmbrCentral::MaterialOwnerRequestBus, SetMaterial, nullptr); - } - } - - ValidateMeshStatObject(); -} - -CMaterial* CComponentEntityObject::GetMaterial() const -{ - _smart_ptr material = nullptr; - EBUS_EVENT_ID_RESULT(material, m_entityId, LmbrCentral::MaterialOwnerRequestBus, GetMaterial); - return GetIEditor()->GetMaterialManager()->FromIMaterial(material); -} - -CMaterial* CComponentEntityObject::GetRenderMaterial() const -{ - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, m_entityId); - if (entity) - { - _smart_ptr material = nullptr; - EBUS_EVENT_ID_RESULT(material, m_entityId, LmbrCentral::MaterialOwnerRequestBus, GetMaterial); - - if (material) - { - return GetIEditor()->GetMaterialManager()->LoadMaterial(material->GetName(), false); - } - } - - return nullptr; -} - -void CComponentEntityObject::ValidateMeshStatObject() -{ - IStatObj* statObj = GetIStatObj(); - CMaterial* editorMaterial = GetMaterial(); - CStatObjValidator statValidator; - statValidator.Validate(statObj, editorMaterial); -} - diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h index 41619d75c5..b64bd6b3e1 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/Objects/ComponentEntityObject.h @@ -79,9 +79,6 @@ public: CBaseObject* GetLinkParent() const override; XmlNodeRef Export(const QString& levelPath, XmlNodeRef& xmlNode) override; void DeleteEntity() override; - void SetMaterial(CMaterial* mtl) override; - CMaterial* GetMaterial() const override; - CMaterial* GetRenderMaterial() const override; void DrawDefault(DisplayContext& dc, const QColor& labelColor = QColor(255, 255, 255)) override; IStatObj* GetIStatObj() override; bool IsIsolated() const override; @@ -184,8 +181,6 @@ protected: void DrawAccent(DisplayContext& dc); - void ValidateMeshStatObject(); - class EditorActionGuard { public: diff --git a/Code/Tools/AssetBundler/source/ui/AssetBundlerTabWidget.cpp b/Code/Tools/AssetBundler/source/ui/AssetBundlerTabWidget.cpp index 2719944af4..9dcfd34c35 100644 --- a/Code/Tools/AssetBundler/source/ui/AssetBundlerTabWidget.cpp +++ b/Code/Tools/AssetBundler/source/ui/AssetBundlerTabWidget.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -232,8 +233,8 @@ namespace AssetBundler for (const QJsonValue scanPath : m_watchedFiles + m_watchedFolders) { - AZStd::string scanFilePathStr = scanPath.toString().toUtf8().data(); - AzFramework::StringFunc::Path::ConstructFull(GetCachedEngineRoot().c_str(), scanFilePathStr.c_str(), scanFilePathStr); + auto scanFilePathStr = (AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) + / scanPath.toString().toUtf8().data()).LexicallyNormal(); // Check whether the file has already been watched // Get absolute file paths via QFileInfo to keep consistency in the letter case @@ -263,8 +264,8 @@ namespace AssetBundler for (auto itr = scanPaths.begin(); itr != scanPaths.end(); ++itr) { QJsonValueRef scanPathValueRef = *itr; - AZStd::string scanPath = scanPathValueRef.toString().toUtf8().data(); - AzFramework::StringFunc::Path::ConstructFull(GetCachedEngineRoot().c_str(), scanPath.c_str(), scanPath); + auto scanPath = (AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) + / scanPathValueRef.toString().toUtf8().data()).LexicallyNormal(); // Check whether the file is being watched // Get absolute file paths via QFileInfo to keep consistency in the letter case @@ -316,13 +317,8 @@ namespace AssetBundler for (const QJsonValue scanPath : scanPaths[AssetBundlingFileTypes[fileType]].toArray()) { - AZStd::string absoluteScanPath = scanPath.toString().toUtf8().data(); - AZStd::replace(absoluteScanPath.begin(), absoluteScanPath.end(), AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - if (AzFramework::StringFunc::Path::IsRelative(absoluteScanPath.c_str())) - { - AzFramework::StringFunc::Path::ConstructFull(GetCachedEngineRoot().c_str(), absoluteScanPath.c_str(), absoluteScanPath); - } + auto absoluteScanPath = (AZ::IO::Path(AZStd::string_view{ AZ::Utils::GetEnginePath() }) + / scanPath.toString().toUtf8().data()).LexicallyNormal(); if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(absoluteScanPath.c_str())) { diff --git a/Code/Tools/AssetBundler/source/ui/SeedTabWidget.cpp b/Code/Tools/AssetBundler/source/ui/SeedTabWidget.cpp index b05a2e0c90..60b4104c5a 100644 --- a/Code/Tools/AssetBundler/source/ui/SeedTabWidget.cpp +++ b/Code/Tools/AssetBundler/source/ui/SeedTabWidget.cpp @@ -138,7 +138,7 @@ namespace AssetBundler m_watchedFolders.insert(m_guiApplicationManager->GetSeedListsFolder().c_str()); // Get the list of default Seed List files - m_filePathToGemNameMap = AssetBundler::GetDefaultSeedListFiles(GetCachedEngineRoot().c_str(), m_guiApplicationManager->GetCurrentProjectName(), + m_filePathToGemNameMap = AssetBundler::GetDefaultSeedListFiles(AZStd::string_view{ AZ::Utils::GetEnginePath() }, m_guiApplicationManager->GetCurrentProjectName(), m_guiApplicationManager->GetGemInfoList(), m_guiApplicationManager->GetEnabledPlatforms()); // Get the list of default Seeds that are not stored in a Seed List file on-disk diff --git a/Code/Tools/AssetBundler/source/utils/applicationManager.cpp b/Code/Tools/AssetBundler/source/utils/applicationManager.cpp index 7aae023e72..ccf5427771 100644 --- a/Code/Tools/AssetBundler/source/utils/applicationManager.cpp +++ b/Code/Tools/AssetBundler/source/utils/applicationManager.cpp @@ -45,13 +45,6 @@ namespace AssetBundler { const char compareVariablePrefix = '$'; - GemInfo::GemInfo(AZStd::string name, AZStd::string relativeFilePath, AZStd::string absoluteFilePath) - : m_gemName(name) - , m_relativeFilePath(relativeFilePath) - , m_absoluteFilePath(absoluteFilePath) - { - } - ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent) : QObject(parent) , AzToolsFramework::ToolsApplication(argc, argv) @@ -80,8 +73,6 @@ namespace AssetBundler m_assetSeedManager = AZStd::make_unique(); AZ_TracePrintf(AssetBundler::AppWindowName, "\n"); - g_cachedEngineRoot = AZ::IO::FixedMaxPath(GetEngineRoot()); - // There is no need to update the UserSettings file, so we can avoid a race condition by disabling save on shutdown AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); return true; @@ -383,6 +374,13 @@ namespace AssetBundler { using namespace AzToolsFramework; + auto validateArgsOutcome = ValidateInputArgs(parser, m_allSeedsArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpSeeds(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + SeedsParams params; params.m_ignoreFileCase = parser->HasSwitch(IgnoreFileCaseFlag); @@ -473,6 +471,13 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseAssetListsCommandData(const AZ::CommandLine* parser) { + auto validateArgsOutcome = ValidateInputArgs(parser, m_allAssetListsArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpAssetLists(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + AssetListsParams params; // Read in Platform arg @@ -536,6 +541,13 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseComparisonRulesCommandData(const AZ::CommandLine* parser) { + auto validateArgsOutcome = ValidateInputArgs(parser, m_allComparisonRulesArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpComparisonRules(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + ScopedTraceHandler traceHandler; ComparisonRulesParams params; @@ -918,6 +930,13 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseCompareCommandData(const AZ::CommandLine* parser) { + auto validateArgsOutcome = ValidateInputArgs(parser, m_allCompareArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpCompare(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + ComparisonParams params; // Read in Platform arg @@ -1009,6 +1028,13 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseBundleSettingsCommandData(const AZ::CommandLine* parser) { + auto validateArgsOutcome = ValidateInputArgs(parser, m_allBundleSettingsArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpBundleSettings(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + BundleSettingsParams params; // Read in Platform arg @@ -1213,6 +1239,13 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseBundlesCommandData(const AZ::CommandLine* parser) { + auto validateArgsOutcome = ValidateInputArgs(parser, m_allBundlesArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpBundles(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + auto parseSettingsOutcome = ParseBundleSettingsAndOverrides(parser, BundlesCommand); if (!parseSettingsOutcome.IsSuccess()) { @@ -1224,6 +1257,14 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ParseBundleSeedCommandData(const AZ::CommandLine* parser) { + + auto validateArgsOutcome = ValidateInputArgs(parser, m_allBundleSeedArgs); + if (!validateArgsOutcome.IsSuccess()) + { + OutputHelpBundleSeed(); + return AZ::Failure(validateArgsOutcome.TakeError()); + } + BundleSeedParams params; params.m_addSeedList = GetAddSeedArgList(parser); @@ -1241,6 +1282,12 @@ namespace AssetBundler AZ::Outcome ApplicationManager::ValidateInputArgs(const AZ::CommandLine* parser, const AZStd::vector& validArgList) { + constexpr AZStd::string_view ApplicationArgList = "/O3DE/AzCore/Application/ValidCommandOptions"; + AZStd::vector validApplicationArgs; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + settingsRegistry->GetObject(validApplicationArgs, ApplicationArgList); + } for (const auto& paramInfo : *parser) { // Skip positional arguments @@ -1258,10 +1305,18 @@ namespace AssetBundler break; } } + for (const auto& validArg : validApplicationArgs) + { + if (AZ::StringFunc::Equal(paramInfo.m_option, validArg)) + { + isValidArg = true; + break; + } + } if (!isValidArg) { - return AZ::Failure(AZStd::string::format("Unknown argument: \"--%s\" is not an unknown argument for this sub-command.", paramInfo.m_option.c_str())); + return AZ::Failure(AZStd::string::format(R"(Invalid argument: "--%s" is not a valid argument for this sub-command.)", paramInfo.m_option.c_str())); } } @@ -1346,10 +1401,10 @@ namespace AssetBundler } // If no platform was specified, defaulting to platforms specified in the asset processor config files - const char* appRoot = nullptr; - AzFramework::ApplicationRequests::Bus::BroadcastResult(appRoot, &AzFramework::ApplicationRequests::GetAppRoot); - - AzFramework::PlatformFlags platformFlags = GetEnabledPlatformFlags(GetEngineRoot(), appRoot, AZ::Utils::GetProjectPath().c_str()); + AzFramework::PlatformFlags platformFlags = GetEnabledPlatformFlags( + AZStd::string_view{ AZ::Utils::GetEnginePath() }, + AZStd::string_view{ AZ::Utils::GetEnginePath() }, + AZStd::string_view{ AZ::Utils::GetProjectPath() }); auto platformsString = AzFramework::PlatformHelper::GetCommaSeparatedPlatformList(platformFlags); AZ_TracePrintf(AppWindowName, "No platform specified, defaulting to platforms ( %s ).\n", platformsString.c_str()); diff --git a/Code/Tools/AssetBundler/source/utils/utils.cpp b/Code/Tools/AssetBundler/source/utils/utils.cpp index 6058728a76..39bc1a7e13 100644 --- a/Code/Tools/AssetBundler/source/utils/utils.cpp +++ b/Code/Tools/AssetBundler/source/utils/utils.cpp @@ -109,17 +109,15 @@ namespace AssetBundler const char* AssetCatalogFilename = "assetcatalog.xml"; - AZ::IO::FixedMaxPath g_cachedEngineRoot; - - const char EngineDirectoryName[] = "Engine"; + constexpr auto EngineDirectoryName = AZ::IO::FixedMaxPath("Assets") / "Engine"; const char RestrictedDirectoryName[] = "restricted"; const char PlatformsDirectoryName[] = "Platforms"; const char GemsDirectoryName[] = "Gems"; const char GemsAssetsDirectoryName[] = "Assets"; const char GemsSeedFileName[] = "seedList"; const char EngineSeedFileName[] = "SeedAssetList"; - + namespace Internal { @@ -131,7 +129,7 @@ namespace AssetBundler AZStd::unordered_map& defaultSeedLists, AzFramework::PlatformFlags platformFlags) { - AZ::IO::FixedMaxPath engineRoot(GetCachedEngineRoot()); + AZ::IO::FixedMaxPath engineRoot(AZ::Utils::GetEnginePath()); AZ::IO::FixedMaxPath engineRestrictedRoot = engineRoot / RestrictedDirectoryName; AZ::IO::FixedMaxPath engineLocalPath = AZ::IO::PathView(engineDirectory.LexicallyRelative(engineRoot)); @@ -204,12 +202,6 @@ namespace AssetBundler } } - AZ::IO::FixedMaxPath GetCachedEngineRoot() - { - AZ_Error(AppWindowName, !g_cachedEngineRoot.empty(), "Cached Engine Root has not been initialized by the Bundler."); - return g_cachedEngineRoot; - } - void AddPlatformIdentifier(AZStd::string& filePath, const AZStd::string& platformIdentifier) { AZStd::string fileName; @@ -257,11 +249,11 @@ namespace AssetBundler absoluteEngineSeedFilePath.ReplaceExtension(AzToolsFramework::AssetSeedManager::GetSeedFileExtension()); if (fileIO->Exists(absoluteEngineSeedFilePath.c_str())) { - defaultSeedLists[absoluteEngineSeedFilePath.Native()] = EngineDirectoryName; + defaultSeedLists[absoluteEngineSeedFilePath.Native()] = EngineDirectoryName.String(); } // Add Seed Lists from the Platforms directory - Internal::AddPlatformsDirectorySeeds(engineDirectory, EngineDirectoryName, defaultSeedLists, platformFlag); + Internal::AddPlatformsDirectorySeeds(engineDirectory, EngineDirectoryName.String(), defaultSeedLists, platformFlag); auto absoluteProjectDefaultSeedFilePath = AZ::IO::Path(projectPath) / EngineSeedFileName; absoluteProjectDefaultSeedFilePath.ReplaceExtension(AzToolsFramework::AssetSeedManager::GetSeedFileExtension()); diff --git a/Code/Tools/AssetBundler/source/utils/utils.h b/Code/Tools/AssetBundler/source/utils/utils.h index 629fd90a31..454a279878 100644 --- a/Code/Tools/AssetBundler/source/utils/utils.h +++ b/Code/Tools/AssetBundler/source/utils/utils.h @@ -122,20 +122,8 @@ namespace AssetBundler //////////////////////////////////////////////////////////////////////////////////////////// extern const char* AssetCatalogFilename; - extern AZ::IO::FixedMaxPath g_cachedEngineRoot; static const size_t MaxErrorMessageLength = 4096; - //! This struct stores gem related information - struct GemInfo - { - AZ_CLASS_ALLOCATOR(GemInfo, AZ::SystemAllocator, 0); - GemInfo(AZStd::string name, AZStd::string relativeFilePath, AZStd::string absoluteFilePath); - GemInfo() = default; - AZStd::string m_gemName; - AZStd::string m_relativeFilePath; - AZStd::string m_absoluteFilePath; - }; - // The Warning Absorber is used to absorb warnings // One case that this is being used is during loading of the asset catalog. @@ -151,9 +139,6 @@ namespace AssetBundler bool OnPreWarning(const char* window, const char* fileName, int line, const char* func, const char* message) override; }; - // Returns the cached engine root. Throws an error if the cached path has not been initialized by the Bundler Application. - AZ::IO::FixedMaxPath GetCachedEngineRoot(); - /** * Determines the name of the currently enabled game project * @return Current Project name on success, error message on failure diff --git a/Code/Tools/AssetBundler/tests/Engine/SeedAssetList.seed b/Code/Tools/AssetBundler/tests/Assets/Engine/SeedAssetList.seed similarity index 100% rename from Code/Tools/AssetBundler/tests/Engine/SeedAssetList.seed rename to Code/Tools/AssetBundler/tests/Assets/Engine/SeedAssetList.seed diff --git a/Code/Tools/AssetBundler/tests/tests_main.cpp b/Code/Tools/AssetBundler/tests/tests_main.cpp index 6d874a3320..9e12623b0d 100644 --- a/Code/Tools/AssetBundler/tests/tests_main.cpp +++ b/Code/Tools/AssetBundler/tests/tests_main.cpp @@ -88,7 +88,7 @@ namespace AssetBundler const char RelativeTestFolder[] = "Code/Tools/AssetBundler/tests"; const char GemsFolder[] = "Gems"; - const char EngineFolder[] = "Engine"; + constexpr auto EngineFolder = AZ::IO::FixedMaxPath("Assets") / "Engine"; const char PlatformsFolder[] = "Platforms"; const char DummyProjectFolder[] = "DummyProject"; @@ -113,13 +113,14 @@ namespace AssetBundler AZ::SettingsRegistry::Register(&m_registry); } - AssetBundler::g_cachedEngineRoot = m_data->m_application.get()->GetEngineRoot(); - if (AssetBundler::g_cachedEngineRoot.empty()) + AZ::IO::FixedMaxPath engineRoot = AZ::Utils::GetEnginePath(); + if (engineRoot.empty()) { GTEST_FATAL_FAILURE_(AZStd::string::format("Unable to locate engine root.\n").c_str()); } - AzFramework::StringFunc::Path::Join(AssetBundler::g_cachedEngineRoot.c_str(), RelativeTestFolder, m_data->m_testEngineRoot); + + m_data->m_testEngineRoot = (engineRoot / RelativeTestFolder).LexicallyNormal().String(); m_data->m_localFileIO = aznew AZ::IO::LocalFileIO(); m_data->m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); @@ -131,8 +132,8 @@ namespace AssetBundler AddGemData(m_data->m_testEngineRoot.c_str(), "GemA"); AddGemData(m_data->m_testEngineRoot.c_str(), "GemB"); - AZStd::string absoluteEngineSeedFilePath; - AzFramework::StringFunc::Path::ConstructFull(m_data->m_testEngineRoot.c_str(), EngineFolder, "SeedAssetList", AzToolsFramework::AssetSeedManager::GetSeedFileExtension(), absoluteEngineSeedFilePath, true); + auto absoluteEngineSeedFilePath = m_data->m_testEngineRoot / EngineFolder / "SeedAssetList"; + absoluteEngineSeedFilePath.ReplaceExtension(AzToolsFramework::AssetSeedManager::GetSeedFileExtension()); m_data->m_gemSeedFilePairList.emplace_back(AZStd::make_pair(absoluteEngineSeedFilePath, true)); AddGemData(m_data->m_testEngineRoot.c_str(), "GemC", false); @@ -212,7 +213,7 @@ namespace AssetBundler AZStd::unique_ptr m_application = {}; AZ::IO::FileIOBase* m_priorFileIO = nullptr; AZ::IO::FileIOBase* m_localFileIO = nullptr; - AZStd::string m_testEngineRoot; + AZ::IO::Path m_testEngineRoot; }; const int GemAIndex = 0; diff --git a/Code/Tools/AssetProcessor/native/utilities/MissingDependencyScanner.cpp b/Code/Tools/AssetProcessor/native/utilities/MissingDependencyScanner.cpp index 73125fd58a..9daf97cf79 100644 --- a/Code/Tools/AssetProcessor/native/utilities/MissingDependencyScanner.cpp +++ b/Code/Tools/AssetProcessor/native/utilities/MissingDependencyScanner.cpp @@ -20,30 +20,32 @@ AZ_POP_DISABLE_WARNING #include "native/AssetDatabase/AssetDatabase.h" #include "native/assetprocessor.h" #include +#include #include #include #include #include +#include #include #include #include #include -#include namespace AssetProcessor { - const char* EngineFolder = "Engine"; + constexpr auto EngineFolder = AZ::IO::FixedMaxPath("Assets") / "Engine"; AZStd::string GetXMLDependenciesFile(const AZStd::string& fullPath, const AZStd::vector& gemInfoList, AZStd::string& tokenName) { AZ::IO::Path xmlDependenciesFileFullPath; - tokenName = EngineFolder; + tokenName = EngineFolder.String(); for (const AzFramework::GemInfo& gemElement : gemInfoList) { for (const AZ::IO::Path& absoluteSourcePath : gemElement.m_absoluteSourcePaths) { - if (AZ::StringFunc::StartsWith(fullPath, absoluteSourcePath.Native()) || AZ::StringFunc::Equal(absoluteSourcePath.Native(), fullPath)) + if (AZ::IO::PathView(fullPath).IsRelativeTo(absoluteSourcePath)) { + xmlDependenciesFileFullPath = absoluteSourcePath; xmlDependenciesFileFullPath /= AzFramework::GemInfo::GetGemAssetFolder(); xmlDependenciesFileFullPath /= AZStd::string::format("%s_Dependencies.xml", gemElement.m_gemName.c_str());; if (AZ::IO::FileIOBase::GetInstance()->Exists(xmlDependenciesFileFullPath.c_str())) @@ -57,7 +59,7 @@ namespace AssetProcessor // if we are here than either the %gemName%_Dependencies.xml file does not exists or the user inputted path is not inside a gems folder, // in both the cases we will return the engine dependencies file - xmlDependenciesFileFullPath = AZ::IO::FileIOBase::GetInstance()->GetAlias("@devroot@"); + xmlDependenciesFileFullPath = AZ::Utils::GetEnginePath(); xmlDependenciesFileFullPath /= EngineFolder; xmlDependenciesFileFullPath /= "Engine_Dependencies.xml"; diff --git a/Gems/AWSCore/Code/CMakeLists.txt b/Gems/AWSCore/Code/CMakeLists.txt index 468530be31..a58b02d1d4 100644 --- a/Gems/AWSCore/Code/CMakeLists.txt +++ b/Gems/AWSCore/Code/CMakeLists.txt @@ -86,7 +86,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) ) ly_add_target( - NAME AWSCore.ResourceMappintTool MODULE + NAME AWSCore.ResourceMappingTool MODULE NAMESPACE Gem OUTPUT_SUBDIRECTORY AWSCoreEditorQtBin FILES_CMAKE @@ -94,15 +94,11 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS) INCLUDE_DIRECTORIES PRIVATE Include/Private - PUBLIC - Include/Public BUILD_DEPENDENCIES PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Widgets - AZ::AzToolsFramework + Gem::AWSCore.Editor.Static ) - ly_add_dependencies(AWSCore.Editor AWSCore.ResourceMappintTool) + ly_add_dependencies(AWSCore.Editor AWSCore.ResourceMappingTool) endif() ################################################################################ diff --git a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h index 5d7baf19a1..9d779e3629 100644 --- a/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h +++ b/Gems/AWSCore/Code/Include/Public/ScriptCanvas/AWSScriptBehaviorS3.h @@ -75,6 +75,16 @@ namespace AWSCore class AWSScriptBehaviorS3 : public AWSScriptBehaviorBase { + static constexpr const char AWSScriptBehaviorS3Name[] = "AWSScriptBehaviorS3"; + static constexpr const char OutputFileIsEmptyErrorMessage[] = "Request validation failed, output file is empty."; + static constexpr const char OutputFileMissFullPathErrorMessage[] = "Request validation failed, output file miss full path."; + static constexpr const char OutputFileIsDirectoryErrorMessage[] = "Request validation failed, output file is a directory."; + static constexpr const char OutputFileDirectoryNotExistErrorMessage[] = "Request validation failed, output file directory doesn't exist."; + static constexpr const char OutputFileIsReadOnlyErrorMessage[] = "Request validation failed, output file is read-only."; + static constexpr const char BucketNameIsEmptyErrorMessage[] = "Request validation failed, bucket name is empty"; + static constexpr const char ObjectKeyNameIsEmptyErrorMessage[] = "Request validation failed, object key name is empty."; + static constexpr const char RegionNameIsEmptyErrorMessage[] = "Request validation failed, region name is empty."; + public: AWS_SCRIPT_BEHAVIOR_DEFINITION(AWSScriptBehaviorS3, "{7F4E956C-7463-4236-B320-C992D36A9C6E}"); @@ -87,7 +97,7 @@ namespace AWSCore private: using S3NotificationFunctionType = void(AWSScriptBehaviorS3Notifications::*)(const AZStd::string&); static bool ValidateGetObjectRequest(S3NotificationFunctionType notificationFunc, - const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, const AZStd::string& outFile); + const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, AZStd::string& outFile); static bool ValidateHeadObjectRequest(S3NotificationFunctionType notificationFunc, const AZStd::string& bucket, const AZStd::string& key, const AZStd::string& region); diff --git a/Gems/AWSCore/Code/Source/AWSCoreResourceMappingToolModule.cpp b/Gems/AWSCore/Code/Source/AWSCoreResourceMappingToolModule.cpp new file mode 100644 index 0000000000..794ee6c880 --- /dev/null +++ b/Gems/AWSCore/Code/Source/AWSCoreResourceMappingToolModule.cpp @@ -0,0 +1,44 @@ +/* +* 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 +#include + +namespace AWSCore +{ + class AWSCoreResourceMappingToolModule + : public AZ::Module + { + public: + AZ_RTTI(AWSCoreResourceMappingToolModule, "{9D16F400-009C-47FF-A186-E48BEB73D94D}", AZ::Module); + AZ_CLASS_ALLOCATOR(AWSCoreResourceMappingToolModule, AZ::SystemAllocator, 0); + + AWSCoreResourceMappingToolModule() + { + m_descriptors.insert(m_descriptors.end(), + { + AWSCoreEditorSystemComponent::CreateDescriptor(), + }); + } + + ~AWSCoreResourceMappingToolModule() override = default; + + AZ::ComponentTypeList GetRequiredSystemComponents() const override + { + return AZ::ComponentTypeList{azrtti_typeid()}; + } + }; +} + +// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM +// The first parameter should be GemName_GemIdLower +// The second should be the fully qualified name of the class above +AZ_DECLARE_MODULE_CLASS(Gem_AWSCore_ResourceMappingTool, AWSCore::AWSCoreResourceMappingToolModule) diff --git a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp index 742a6826af..1f529572f1 100644 --- a/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp +++ b/Gems/AWSCore/Code/Source/ScriptCanvas/AWSScriptBehaviorS3.cpp @@ -43,7 +43,7 @@ namespace AWSCore void AWSScriptBehaviorS3::ReflectBehaviors(AZ::BehaviorContext* behaviorContext) { - behaviorContext->Class("AWSScriptBehaviorS3") + behaviorContext->Class(AWSScriptBehaviorS3Name) ->Attribute(AZ::Script::Attributes::Category, "AWSCore") ->Method("GetObject", &AWSScriptBehaviorS3::GetObject, {{{"Bucket Resource KeyName", "The resource key name of the bucket in resource mapping config file."}, @@ -86,7 +86,9 @@ namespace AWSCore void AWSScriptBehaviorS3::GetObjectRaw( const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, const AZStd::string& outFile) { - if (!ValidateGetObjectRequest(&AWSScriptBehaviorS3NotificationBus::Events::OnGetObjectError, bucket, objectKey, region, outFile)) + AZStd::string normalizedOutFile = outFile; + if (!ValidateGetObjectRequest( + &AWSScriptBehaviorS3NotificationBus::Events::OnGetObjectError, bucket, objectKey, region, normalizedOutFile)) { return; } @@ -112,10 +114,10 @@ namespace AWSCore job->request.SetBucket(Aws::String(bucket.c_str())); job->request.SetKey(Aws::String(objectKey.c_str())); - Aws::String outFileName(outFile.c_str()); + Aws::String outFileName(normalizedOutFile.c_str()); job->request.SetResponseStreamFactory([outFileName]() { return Aws::New( - "AWSScriptBehaviorS3", outFileName.c_str(), + AWSScriptBehaviorS3Name, outFileName.c_str(), std::ios_base::out | std::ios_base::in | std::ios_base::binary | std::ios_base::trunc); }); job->Start(); @@ -163,20 +165,44 @@ namespace AWSCore } bool AWSScriptBehaviorS3::ValidateGetObjectRequest(S3NotificationFunctionType notificationFunc, - const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, const AZStd::string& outFile) + const AZStd::string& bucket, const AZStd::string& objectKey, const AZStd::string& region, AZStd::string& outFile) { if (ValidateHeadObjectRequest(notificationFunc, bucket, objectKey, region)) { - if (!AzFramework::StringFunc::Path::IsValid(outFile.c_str())) + AzFramework::StringFunc::Path::Normalize(outFile); + if (outFile.empty()) { - AZ_Warning("AWSScriptBehaviorS3", false, "Request validation failed, outfile is not valid."); - AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, "Request validation failed, outfile is not valid."); + AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileIsEmptyErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileIsEmptyErrorMessage); return false; } + if (!AzFramework::StringFunc::Path::HasDrive(outFile.c_str())) + { + AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileMissFullPathErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileMissFullPathErrorMessage); + return false; + } + if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(outFile.c_str())) + { + AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileIsDirectoryErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileIsDirectoryErrorMessage); + return false; + } + auto lastSeparator = outFile.find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR); + if (lastSeparator != AZStd::string::npos) + { + auto parentPath = outFile.substr(0, lastSeparator); + if (!AZ::IO::FileIOBase::GetInstance()->Exists(parentPath.c_str())) + { + AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileDirectoryNotExistErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileDirectoryNotExistErrorMessage); + return false; + } + } if (AZ::IO::FileIOBase::GetInstance()->IsReadOnly(outFile.c_str())) { - AZ_Warning("AWSScriptBehaviorS3", false, "Request validation failed, outfile is read-only."); - AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, "Request validation failed, outfile is read-only."); + AZ_Warning(AWSScriptBehaviorS3Name, false, OutputFileIsReadOnlyErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, OutputFileIsReadOnlyErrorMessage); return false; } return true; @@ -189,20 +215,20 @@ namespace AWSCore { if (bucket.empty()) { - AZ_Warning("AWSScriptBehaviorS3", false, "Request validation failed, bucket name is required."); - AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, "Request validation failed, bucket name is required."); + AZ_Warning(AWSScriptBehaviorS3Name, false, BucketNameIsEmptyErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, BucketNameIsEmptyErrorMessage); return false; } if (objectKey.empty()) { - AZ_Warning("AWSScriptBehaviorS3", false, "Request validation failed, object key name is required."); - AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, "Request validation failed, object key name is required."); + AZ_Warning(AWSScriptBehaviorS3Name, false, ObjectKeyNameIsEmptyErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, ObjectKeyNameIsEmptyErrorMessage); return false; } if (region.empty()) { - AZ_Warning("AWSScriptBehaviorS3", false, "Request validation failed, region name is required."); - AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, "Request validation failed, region name is required."); + AZ_Warning(AWSScriptBehaviorS3Name, false, RegionNameIsEmptyErrorMessage); + AWSScriptBehaviorS3NotificationBus::Broadcast(notificationFunc, RegionNameIsEmptyErrorMessage); return false; } return true; diff --git a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp index fe258580e0..3489f09ac3 100644 --- a/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp +++ b/Gems/AWSCore/Code/Tests/ScriptCanvas/AWSScriptBehaviorS3Test.cpp @@ -11,6 +11,7 @@ */ #include +#include #include #include @@ -38,7 +39,37 @@ public: MOCK_METHOD1(OnGetObjectError, void(const AZStd::string&)); }; -using AWSScriptBehaviorS3Test = UnitTest::ScopedAllocatorSetupFixture; +class AWSScriptBehaviorS3Test + : public AWSCoreFixture +{ +public: + void CreateReadOnlyTestFile(const AZStd::string& filePath) + { + AZ::IO::SystemFile file; + if (!file.Open( + filePath.c_str(), + AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY)) + { + AZ_Assert(false, "Failed to open test file at %s", filePath.c_str()); + } + AZStd::string testContent = "It is a test file"; + if (file.Write(testContent.c_str(), testContent.size()) != testContent.size()) + { + AZ_Assert(false, "Failed to write test file with content %s", testContent.c_str()); + } + file.Close(); + AZ_Assert(AZ::IO::SystemFile::SetWritable(filePath.c_str(), false), "Failed to mark test file as read-only"); + } + + void RemoveReadOnlyTestFile(const AZStd::string& filePath) + { + if (!filePath.empty()) + { + AZ_Assert(AZ::IO::SystemFile::SetWritable(filePath.c_str(), true), "Failed to mark test file as writeable"); + AZ_Assert(AZ::IO::SystemFile::Delete(filePath.c_str()), "Failed to delete test config file at %s", filePath.c_str()); + } + } +}; TEST_F(AWSScriptBehaviorS3Test, HeadObjectRaw_CallWithEmptyBucketName_InvokeOnError) { @@ -96,6 +127,40 @@ TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithEmptyOutfileName_InvokeOnEr AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", ""); } +TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileNameMissFullPath_InvokeOnError) +{ + AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock; + EXPECT_CALL(s3HandlerMock, OnGetObjectError(::testing::_)).Times(1); + AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", "dummyOut.txt"); +} + +TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileNameIsDirectory_InvokeOnError) +{ + AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock; + EXPECT_CALL(s3HandlerMock, OnGetObjectError(::testing::_)).Times(1); + AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", AZ::Test::GetCurrentExecutablePath()); +} + +TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileDirectoryNoExist_InvokeOnError) +{ + AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock; + EXPECT_CALL(s3HandlerMock, OnGetObjectError(::testing::_)).Times(1); + AZStd::string dummyDirectory = AZStd::string::format("%s/dummyDirectory/dummyOut.txt", AZ::Test::GetCurrentExecutablePath().c_str()); + AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", dummyDirectory); +} + +TEST_F(AWSScriptBehaviorS3Test, GetObjectRaw_CallWithOutfileIsReadOnly_InvokeOnError) +{ + AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock; + EXPECT_CALL(s3HandlerMock, OnGetObjectError(::testing::_)).Times(1); + AZStd::string randomTestFile = AZStd::string::format("%s/test%s.txt", + AZ::Test::GetCurrentExecutablePath().c_str(), AZ::Uuid::CreateRandom().ToString(false, false).c_str()); + AzFramework::StringFunc::Path::Normalize(randomTestFile); + CreateReadOnlyTestFile(randomTestFile); + AWSScriptBehaviorS3::GetObjectRaw("dummyBucket", "dummyObject", "dummyRegion", randomTestFile); + RemoveReadOnlyTestFile(randomTestFile); +} + TEST_F(AWSScriptBehaviorS3Test, GetObject_NoBucketNameInResourceMappingFound_InvokeOnError) { AWSScriptBehaviorS3NotificationBusHandlerMock s3HandlerMock; diff --git a/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake b/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake index b67c50e955..466a2c917f 100644 --- a/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake +++ b/Gems/AWSCore/Code/awscore_resourcemappingtool_files.cmake @@ -10,6 +10,5 @@ # set(FILES - Include/Private/Editor/UI/AWSCoreResourceMappingToolAction.h - Source/Editor/UI/AWSCoreResourceMappingToolAction.cpp + Source/AWSCoreResourceMappingToolModule.cpp ) diff --git a/Gems/AssetValidation/Code/Source/AssetSeedUtil.h b/Gems/AssetValidation/Code/Source/AssetSeedUtil.h index 4a6ff1f1d8..60d94e8903 100644 --- a/Gems/AssetValidation/Code/Source/AssetSeedUtil.h +++ b/Gems/AssetValidation/Code/Source/AssetSeedUtil.h @@ -30,7 +30,7 @@ namespace AssetValidation::AssetSeed constexpr char GemsDirectoryName[] = "Gems"; constexpr char GemsSeedFileName[] = "seedList"; constexpr char EngineSeedFileName[] = "SeedAssetList"; - constexpr char EngineDirectoryName[] = "Engine"; + constexpr auto EngineDirectoryName = AZ::IO::FixedMaxPath("Assets") / "Engine"; void AddPlatformSeeds(const AZStd::string& rootFolder, AZStd::vector& defaultSeedLists, AzFramework::PlatformFlags platformFlags); diff --git a/Gems/AssetValidation/Code/Tests/AssetValidationTest.cpp b/Gems/AssetValidation/Code/Tests/AssetValidationTest.cpp index a5ff671fc3..5003c4484c 100644 --- a/Gems/AssetValidation/Code/Tests/AssetValidationTest.cpp +++ b/Gems/AssetValidation/Code/Tests/AssetValidationTest.cpp @@ -32,20 +32,21 @@ TEST_F(AssetValidationTest, DefaultSeedList_ReturnsExpectedSeedLists) { AZStd::vector gemInfo; - AZStd::string gemSeedList, engineSeedList, projectSeedList; + AZ::IO::Path gemSeedList, engineSeedList, projectSeedList; - ASSERT_TRUE(CreateDummyFile((AZ::IO::Path("mockGem") / AzFramework::GemInfo::GetGemAssetFolder()).c_str(), "seedList", "Mock Gem Seed List", gemSeedList)); - ASSERT_TRUE(CreateDummyFile("Engine", "SeedAssetList", "Engine Seed List", engineSeedList)); + ASSERT_TRUE(CreateDummyFile((AZ::IO::Path("mockGem") / AzFramework::GemInfo::GetGemAssetFolder()).c_str(), "seedList", "Mock Gem Seed List", gemSeedList.Native())); + ASSERT_TRUE(CreateDummyFile((AZ::IO::Path("Assets") / "Engine").c_str(), "SeedAssetList", "Engine Seed List", engineSeedList.Native())); AZ::SettingsRegistryInterface::FixedValueString projectName = AZ::Utils::GetProjectName(); ASSERT_FALSE(projectName.empty()); - ASSERT_TRUE(CreateDummyFile(projectName.c_str(), "SeedAssetList", "Project Seed List", projectSeedList)); + ASSERT_TRUE(CreateDummyFile(projectName.c_str(), "SeedAssetList", "Project Seed List", projectSeedList.Native())); AzFramework::GemInfo mockGem("MockGem"); mockGem.m_absoluteSourcePaths.push_back((m_tempDir / "mockGem").string().c_str()); gemInfo.push_back(mockGem); - AZStd::vector defaultSeedLists = AssetValidation::AssetSeed::GetDefaultSeedListFiles(gemInfo, AzFramework::PlatformFlags::Platform_PC); + AZStd::vector defaultSeedStringList = AssetValidation::AssetSeed::GetDefaultSeedListFiles(gemInfo, AzFramework::PlatformFlags::Platform_PC); + AZStd::vector defaultSeedLists{ AZStd::make_move_iterator(defaultSeedStringList.begin()), AZStd::make_move_iterator(defaultSeedStringList.end()) }; ASSERT_THAT(defaultSeedLists, ::testing::UnorderedElementsAre(gemSeedList, engineSeedList, projectSeedList)); } diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Compressed.preset b/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Compressed.preset index dcbaea96aa..01595a3425 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Compressed.preset +++ b/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Compressed.preset @@ -7,7 +7,10 @@ "UUID": "{2828FBFE-BDF9-45A7-9370-F93822719CCF}", "Name": "UserInterface_Compressed", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8", + "SourceColor": "Linear", + "DestColor": "Linear", + "FileMasks": [ "_ui" ] }, "PlatformsPresets": { "es3": { diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Lossless.preset b/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Lossless.preset index 5ccaa3ac16..78c63790ab 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Lossless.preset +++ b/Gems/Atom/Asset/ImageProcessingAtom/Config/UserInterface_Lossless.preset @@ -7,32 +7,35 @@ "UUID": "{83003128-F63E-422B-AEC2-68F0A947225F}", "Name": "UserInterface_Lossless", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8", + "SourceColor": "Linear", + "DestColor": "Linear", + "FileMasks": [ "_ui" ] }, "PlatformsPresets": { "es3": { "UUID": "{83003128-F63E-422B-AEC2-68F0A947225F}", "Name": "UserInterface_Lossless", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8" }, "ios": { "UUID": "{83003128-F63E-422B-AEC2-68F0A947225F}", "Name": "UserInterface_Lossless", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8" }, "osx_gl": { "UUID": "{83003128-F63E-422B-AEC2-68F0A947225F}", "Name": "UserInterface_Lossless", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8" }, "provo": { "UUID": "{83003128-F63E-422B-AEC2-68F0A947225F}", "Name": "UserInterface_Lossless", "SuppressEngineReduce": true, - "PixelFormat": "R8G8B8X8" + "PixelFormat": "R8G8B8A8" } } } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.cpp new file mode 100644 index 0000000000..138d619d97 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.cpp @@ -0,0 +1,355 @@ +/* +* 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 "AttachmentComponent.h" +#include +#include +#include +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + /// Behavior Context handler for AttachmentComponentNotificationBus + class BehaviorAttachmentComponentNotificationBusHandler : public LmbrCentral::AttachmentComponentNotificationBus::Handler, + public AZ::BehaviorEBusHandler + { + public: + AZ_EBUS_BEHAVIOR_BINDER( + BehaviorAttachmentComponentNotificationBusHandler, "{636B95A0-5C7D-4EE7-8645-955665315451}", AZ::SystemAllocator, + OnAttached, OnDetached); + + void OnAttached(AZ::EntityId id) override + { + Call(FN_OnAttached, id); + } + + void OnDetached(AZ::EntityId id) override + { + Call(FN_OnDetached, id); + } + }; + + void AttachmentConfiguration::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class() + ->Version(1) + ->Field("Target ID", &AttachmentConfiguration::m_targetId) + ->Field("Target Bone Name", &AttachmentConfiguration::m_targetBoneName) + ->Field("Target Offset", &AttachmentConfiguration::m_targetOffset) + ->Field("Attached Initially", &AttachmentConfiguration::m_attachedInitially) + ->Field("Scale Source", &AttachmentConfiguration::m_scaleSource); + } + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) + { + behaviorContext->EBus("AttachmentComponentRequestBus") + ->Event("Attach", &LmbrCentral::AttachmentComponentRequestBus::Events::Attach) + ->Event("Detach", &LmbrCentral::AttachmentComponentRequestBus::Events::Detach) + ->Event("SetAttachmentOffset", &LmbrCentral::AttachmentComponentRequestBus::Events::SetAttachmentOffset); + + behaviorContext->EBus("AttachmentComponentNotificationBus") + ->Handler(); + } + } + + void AttachmentComponent::Reflect(AZ::ReflectContext* context) + { + AttachmentConfiguration::Reflect(context); + + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class()->Version(1)->Field( + "Configuration", &AttachmentComponent::m_initialConfiguration); + } + } + + //========================================================================= + // BoneFollower + //========================================================================= + + void BoneFollower::Activate(AZ::Entity* owner, const AttachmentConfiguration& configuration, bool targetCanAnimate) + { + AZ_Assert(owner, "owner is required"); + AZ_Assert(!m_ownerId.IsValid(), "BoneFollower is already Activated"); + + m_ownerId = owner->GetId(); + m_targetCanAnimate = targetCanAnimate; + m_isUpdatingOwnerTransform = false; + m_scaleSource = configuration.m_scaleSource; + + m_cachedOwnerTransform = AZ::Transform::CreateIdentity(); + EBUS_EVENT_ID_RESULT(m_cachedOwnerTransform, m_ownerId, AZ::TransformBus, GetWorldTM); + + if (configuration.m_attachedInitially) + { + Attach(configuration.m_targetId, configuration.m_targetBoneName.c_str(), configuration.m_targetOffset); + } + + LmbrCentral::AttachmentComponentRequestBus::Handler::BusConnect(m_ownerId); + } + + void BoneFollower::Deactivate() + { + AZ_Assert(m_ownerId.IsValid(), "BoneFollower was never Activated"); + + LmbrCentral::AttachmentComponentRequestBus::Handler::BusDisconnect(); + Detach(); + m_ownerId.SetInvalid(); + } + + AZ::EntityId BoneFollower::GetTargetEntityId() + { + return m_targetId; + } + + AZ::Transform BoneFollower::GetOffset() + { + return m_targetOffset; + } + + void BoneFollower::Attach(AZ::EntityId targetId, const char* targetBoneName, const AZ::Transform& offset) + { + AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use.") + + // safe to try and detach, even if we weren't attached + Detach(); + + if (!targetId.IsValid()) + { + return; + } + + if (targetId == m_ownerId) + { + AZ_Error("Attachment Component", false, "AttachmentComponent cannot target itself"); + return; + } + + // Note: the target entity may not be activated yet. That's ok. + // When mesh is ready we are notified via MeshComponentEvents::OnModelReady + // When transform is ready we are notified via TransformNotificationBus::OnTransformChanged + + m_targetId = targetId; + m_targetBoneName = targetBoneName; + m_targetOffset = offset; + + BindTargetBone(); + + m_targetBoneTransform = AZ::Transform::Identity(); + + m_isTargetEntityTransformKnown = false; // target's transform may not be available yet + + AZ::TransformBus::EventResult( + m_cachedOwnerTransform, m_ownerId, &AZ::TransformBus::Events::GetWorldTM); // owner query will always succeed + + MeshComponentNotificationBus::Handler::BusConnect(m_targetId); // fires OnModelReady if asset is already ready + AZ::TransformNotificationBus::Handler::BusConnect(m_targetId); + if (m_targetCanAnimate) + { + // Only register for per-frame updates when target can animate + AZ::TickBus::Handler::BusConnect(); + } + + // update owner's transform + UpdateOwnerTransformIfNecessary(); + + // alert others that we've attached + LmbrCentral::AttachmentComponentNotificationBus::Event(m_targetId, &LmbrCentral::AttachmentComponentNotificationBus::Events::OnAttached, m_ownerId); + } + + void BoneFollower::Detach() + { + AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use."); + + if (m_targetId.IsValid()) + { + // alert others that we're detaching + EBUS_EVENT_ID(m_targetId, LmbrCentral::AttachmentComponentNotificationBus, OnDetached, m_ownerId); + + MeshComponentNotificationBus::Handler::BusDisconnect(); + AZ::TransformNotificationBus::Handler::BusDisconnect(m_targetId); + AZ::TickBus::Handler::BusDisconnect(); + + m_targetId.SetInvalid(); + } + } + + const char* BoneFollower::GetJointName() + { + return m_targetBoneName.c_str(); + } + + void BoneFollower::SetAttachmentOffset(const AZ::Transform& offset) + { + AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use."); + + if (m_targetId.IsValid()) + { + m_targetOffset = offset; + UpdateOwnerTransformIfNecessary(); + } + } + + void BoneFollower::OnModelReady([[maybe_unused]] const AZ::Data::Asset& modelAsset, [[maybe_unused]] const AZ::Data::Instance& model) + { + // reset character values + BindTargetBone(); + m_targetBoneTransform = QueryBoneTransform(); + + // move owner if necessary + UpdateOwnerTransformIfNecessary(); + } + + void BoneFollower::BindTargetBone() + { + m_targetBoneId = -1; + LmbrCentral::SkeletalHierarchyRequestBus::EventResult( + m_targetBoneId, m_targetId, &LmbrCentral::SkeletalHierarchyRequests::GetJointIndexByName, m_targetBoneName.c_str()); + } + + void BoneFollower::UpdateOwnerTransformIfNecessary() + { + // Can't update until target entity's transform is known + if (!m_isTargetEntityTransformKnown) + { + if (AZ::TransformBus::GetNumOfEventHandlers(m_targetId) == 0) + { + return; + } + + AZ::TransformBus::EventResult(m_targetEntityTransform, m_targetId, &AZ::TransformBus::Events::GetWorldTM); + m_isTargetEntityTransformKnown = true; + } + + AZ::Transform finalTransform; + if (m_scaleSource == AttachmentConfiguration::ScaleSource::WorldScale) + { + // apply offset in world-space + finalTransform = m_targetEntityTransform * m_targetBoneTransform; + finalTransform.SetScale(AZ::Vector3::CreateOne()); + finalTransform *= m_targetOffset; + } + else if (m_scaleSource == AttachmentConfiguration::ScaleSource::TargetEntityScale) + { + // apply offset in target-entity-space (ignoring bone scale) + AZ::Transform boneNoScale = m_targetBoneTransform; + boneNoScale.SetScale(AZ::Vector3::CreateOne()); + + finalTransform = m_targetEntityTransform * boneNoScale * m_targetOffset; + } + else // AttachmentConfiguration::ScaleSource::TargetEntityScale + { + // apply offset in target-bone-space + finalTransform = m_targetEntityTransform * m_targetBoneTransform * m_targetOffset; + } + + if (m_cachedOwnerTransform != finalTransform) + { + AZ_Warning( + "Attachment Component", !m_isUpdatingOwnerTransform, + "AttachmentComponent detected a cycle when updating transform, do not target child entities."); + if (!m_isUpdatingOwnerTransform) + { + m_cachedOwnerTransform = finalTransform; + m_isUpdatingOwnerTransform = true; + EBUS_EVENT_ID(m_ownerId, AZ::TransformBus, SetWorldTM, finalTransform); + m_isUpdatingOwnerTransform = false; + } + } + } + + AZ::Transform BoneFollower::QueryBoneTransform() const + { + AZ::Transform boneTransform = AZ::Transform::CreateIdentity(); + + if (m_targetBoneId >= 0) + { + LmbrCentral::SkeletalHierarchyRequestBus::EventResult( + boneTransform, m_targetId, &LmbrCentral::SkeletalHierarchyRequests::GetJointTransformCharacterRelative, m_targetBoneId); + } + + return boneTransform; + } + + // fires when target's transform changes + void BoneFollower::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) + { + m_targetEntityTransform = world; + m_isTargetEntityTransformKnown = true; + UpdateOwnerTransformIfNecessary(); + } + + void BoneFollower::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) + { + m_targetBoneTransform = QueryBoneTransform(); + UpdateOwnerTransformIfNecessary(); + } + + int BoneFollower::GetTickOrder() + { + return AZ::TICK_ATTACHMENT; + } + + void BoneFollower::Reattach(bool detachFirst) + { +#ifdef AZ_ENABLE_TRACING + AZ::Entity* ownerEntity = nullptr; + AZ::Entity* targetEntity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(ownerEntity, &AZ::ComponentApplicationBus::Events::FindEntity, m_ownerId); + AZ::ComponentApplicationBus::BroadcastResult(targetEntity, &AZ::ComponentApplicationBus::Events::FindEntity, m_targetId); + AZ_TracePrintf( + "BoneFollower", "Reattaching entity '%s' to entity '%s'", ownerEntity ? ownerEntity->GetName().c_str() : "", + targetEntity ? targetEntity->GetName().c_str() : ""); +#endif + + if (m_targetId.IsValid() && detachFirst) + { + LmbrCentral::AttachmentComponentNotificationBus::Event(m_targetId, &LmbrCentral::AttachmentComponentNotificationBus::Events::OnDetached, m_ownerId); + } + + if (m_targetId != m_ownerId) + { + LmbrCentral::AttachmentComponentNotificationBus::Event(m_targetId, &LmbrCentral::AttachmentComponentNotificationBus::Events::OnAttached, m_ownerId); + } + } + + //========================================================================= + // AttachmentComponent + //========================================================================= + + void AttachmentComponent::Activate() + { +#ifdef AZ_ENABLE_TRACING + bool isStaticTransform = false; + AZ::TransformBus::EventResult(isStaticTransform, GetEntityId(), &AZ::TransformBus::Events::IsStaticTransform); + AZ_Warning( + "Attachment Component", !isStaticTransform, "Attachment needs to move, but entity '%s' %s has a static transform.", + GetEntity()->GetName().c_str(), GetEntityId().ToString().c_str()); +#endif + + m_boneFollower.Activate(GetEntity(), m_initialConfiguration, true); + } + + void AttachmentComponent::Deactivate() + { + m_boneFollower.Deactivate(); + } + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h new file mode 100644 index 0000000000..ac03663f22 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/AttachmentComponent.h @@ -0,0 +1,189 @@ +/* +* 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 +#include +#include +#include +#include + +struct ISkeletonPose; + +namespace AZ +{ + namespace Render + { + /*! + * Configuration data for AttachmentComponent. + */ + struct AttachmentConfiguration + { + AZ_TYPE_INFO(AttachmentConfiguration, "{74B5DC69-DE44-4640-836A-55339E116795}"); + + virtual ~AttachmentConfiguration() = default; + + static void Reflect(AZ::ReflectContext* context); + + //! Attach to this entity. + AZ::EntityId m_targetId; + + //! Attach to this bone on target entity. + AZStd::string m_targetBoneName; + + //! Offset from target. + AZ::Transform m_targetOffset = AZ::Transform::Identity(); + + //! Whether to attach to target upon activation. + //! If false, the entity remains detached until Attach() is called. + bool m_attachedInitially = true; + + //! Source from which to retrieve scale information. + enum class ScaleSource : AZ::u8 + { + WorldScale, // Scaled in world space. + TargetEntityScale, // Adopt scaling of attachment target entity. + TargetBoneScale, // Adopt scaling of attachment target entity/joint. + }; + ScaleSource m_scaleSource = ScaleSource::WorldScale; + }; + + /* + * Common functionality for game and editor attachment components. + * The BoneFollower tracks movement of the target's bone and + * updates the owning entity's TransformComponent to follow. + * This class should be a member within the attachment component + * and be activated/deactivated along with the component. + * \ref AttachmentComponent + */ + class BoneFollower + : public LmbrCentral::AttachmentComponentRequestBus::Handler + , public AZ::TransformNotificationBus::Handler + , public AZ::Render::MeshComponentNotificationBus::Handler + , public AZ::Data::AssetBus::Handler + , public AZ::TickBus::Handler + { + public: + void Activate(AZ::Entity* owner, const AttachmentConfiguration& initialConfiguration, bool targetCanAnimate); + void Deactivate(); + + //////////////////////////////////////////////////////////////////////// + // AttachmentComponentRequests + void Reattach(bool detachFirst); + void Attach(AZ::EntityId targetId, const char* targetBoneName, const AZ::Transform& offset) override; + void Detach() override; + void SetAttachmentOffset(const AZ::Transform& offset) override; + const char* GetJointName() override; + AZ::EntityId GetTargetEntityId() override; + AZ::Transform GetOffset() override; + //////////////////////////////////////////////////////////////////////// + + private: + + //////////////////////////////////////////////////////////////////////// + // AZ::TickBus + //! Check target bone transform every frame. + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + //! Make sure target bone transform updates after animation update. + int GetTickOrder() override; + //////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////// + // AZ::TransformNotificationBus + //! When target's transform changes + void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; + //////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////// + // MeshComponentEvents + //! When target's mesh changes + void OnModelReady(const AZ::Data::Asset& modelAsset, const AZ::Data::Instance& model) override; + //////////////////////////////////////////////////////////////////////// + + void BindTargetBone(); + + AZ::Transform QueryBoneTransform() const; + + void UpdateOwnerTransformIfNecessary(); + + //! Entity which which is being attached. + AZ::EntityId m_ownerId; + + //! Whether to query bone position per-frame (false while in editor) + bool m_targetCanAnimate = false; + + AZ::EntityId m_targetId; + AZStd::string m_targetBoneName; + AZ::Transform m_targetOffset; //!< local transform + AZ::Transform m_targetBoneTransform; //!< local transform of bone + AZ::Transform m_targetEntityTransform; //!< world transform of target + bool m_isTargetEntityTransformKnown = false; + + //! Cached value, so we don't update owner's position unnecessarily. + AZ::Transform m_cachedOwnerTransform; + bool m_isUpdatingOwnerTransform = false; //!< detect infinite loops when updating owner's transform + + // Cached character values to avoid repeated lookup. + // These are set by calling ResetCharacter() + int m_targetBoneId; //!< negative when bone not found + + AttachmentConfiguration::ScaleSource m_scaleSource; + }; + + /*! + * The AttachmentComponent lets an entity stick to a particular bone on + * a target entity. This is achieved by tracking movement of the target's + * bone and updating the entity's TransformComponent accordingly. + */ + class AttachmentComponent + : public AZ::Component + { + public: + AZ_COMPONENT(AttachmentComponent, "{2D17A64A-7AC5-4C02-AC36-C5E8141FFDDF}"); + + friend class EditorAttachmentComponent; + + static void Reflect(AZ::ReflectContext* context); + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + provided.push_back(AZ_CRC("AttachmentService", 0x5aaa7b63)); + } + + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + incompatible.push_back(AZ_CRC("AttachmentService", 0x5aaa7b63)); + } + + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); + } + + ~AttachmentComponent() override = default; + + private: + //////////////////////////////////////////////////////////////////////// + // AZ::Component + void Activate() override; + void Deactivate() override; + //////////////////////////////////////////////////////////////////////// + + //! Initial configuration for m_attachment + AttachmentConfiguration m_initialConfiguration; + + //! Implements actual attachment functionality + BoneFollower m_boneFollower; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.cpp new file mode 100644 index 0000000000..3b50c0a48c --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.cpp @@ -0,0 +1,242 @@ +/* +* 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 "EditorAttachmentComponent.h" +#include +#include +#include +#include +#include + +namespace AZ +{ + namespace Render + { + void EditorAttachmentComponent::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class() + ->Version(1) + ->Field("Target ID", &EditorAttachmentComponent::m_targetId) + ->Field("Target Bone Name", &EditorAttachmentComponent::m_targetBoneName) + ->Field("Position Offset", &EditorAttachmentComponent::m_positionOffset) + ->Field("Rotation Offset", &EditorAttachmentComponent::m_rotationOffset) + ->Field("Scale Offset", &EditorAttachmentComponent::m_scaleOffset) + ->Field("Attached Initially", &EditorAttachmentComponent::m_attachedInitially) + ->Field("Scale Source", &EditorAttachmentComponent::m_scaleSource); + + AZ::EditContext* editContext = serializeContext->GetEditContext(); + if (editContext) + { + editContext + ->Class( + "Attachment", "The Attachment component lets an entity attach to a bone on the skeleton of another entity") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Category, "Animation") + ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Attachment.svg") + ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Attachment.png") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute( + AZ::Edit::Attributes::HelpPageURL, + "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-attachment.html") + ->DataElement(0, &EditorAttachmentComponent::m_targetId, "Target entity", "Attach to this entity.") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetIdChanged) + ->DataElement( + AZ::Edit::UIHandlers::ComboBox, &EditorAttachmentComponent::m_targetBoneName, "Joint name", + "Attach to this joint on target entity.") + ->Attribute(AZ::Edit::Attributes::StringList, &EditorAttachmentComponent::GetTargetBoneOptions) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetBoneChanged) + ->DataElement( + 0, &EditorAttachmentComponent::m_positionOffset, "Position offset", "Local position offset from target bone") + ->Attribute(AZ::Edit::Attributes::Suffix, "m") + ->Attribute(AZ::Edit::Attributes::Step, 0.01f) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) + ->DataElement( + 0, &EditorAttachmentComponent::m_rotationOffset, "Rotation offset", "Local rotation offset from target bone") + ->Attribute(AZ::Edit::Attributes::Suffix, "deg") + ->Attribute(AZ::Edit::Attributes::Step, 0.01f) + ->Attribute(AZ::Edit::Attributes::Min, -AZ::RadToDeg(AZ::Constants::TwoPi)) + ->Attribute(AZ::Edit::Attributes::Max, AZ::RadToDeg(AZ::Constants::TwoPi)) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) + ->DataElement(0, &EditorAttachmentComponent::m_scaleOffset, "Scale offset", "Local scale offset from target entity") + ->Attribute(AZ::Edit::Attributes::Step, 0.1f) + ->Attribute(AZ::Edit::Attributes::Min, 0.001f) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) + ->DataElement( + 0, &EditorAttachmentComponent::m_attachedInitially, "Attached initially", + "Whether to attach to target upon activation.") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnAttachedInitiallyChanged) + ->DataElement( + AZ::Edit::UIHandlers::ComboBox, &EditorAttachmentComponent::m_scaleSource, "Scaling", + "How object scale should be determined. " + "Use world scale = Attached object is scaled in world space, Use target entity scale = Attached object adopts " + "scale of target entity., Use target bone scale = Attached object adopts scale of target entity/joint.") + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnScaleSourceChanged) + ->EnumAttribute(AttachmentConfiguration::ScaleSource::WorldScale, "Use world scale") + ->EnumAttribute(AttachmentConfiguration::ScaleSource::TargetEntityScale, "Use target entity scale") + ->EnumAttribute(AttachmentConfiguration::ScaleSource::TargetBoneScale, "Use target bone scale"); + } + } + } + + void EditorAttachmentComponent::Activate() + { + Base::Activate(); + m_boneFollower.Activate(GetEntity(), CreateAttachmentConfiguration(), + false); // Entity's don't animate in Editor + } + + void EditorAttachmentComponent::Deactivate() + { + m_boneFollower.Deactivate(); + Base::Deactivate(); + } + + void EditorAttachmentComponent::BuildGameEntity(AZ::Entity* gameEntity) + { + AttachmentComponent* component = gameEntity->CreateComponent(); + if (component) + { + component->m_initialConfiguration = CreateAttachmentConfiguration(); + } + } + + AttachmentConfiguration EditorAttachmentComponent::CreateAttachmentConfiguration() const + { + AttachmentConfiguration configuration; + configuration.m_targetId = m_targetId; + configuration.m_targetBoneName = m_targetBoneName; + configuration.m_targetOffset = GetTargetOffset(); + configuration.m_attachedInitially = m_attachedInitially; + configuration.m_scaleSource = m_scaleSource; + return configuration; + } + + AZ::Transform EditorAttachmentComponent::GetTargetOffset() const + { + AZ::Transform offset = AZ::ConvertEulerDegreesToTransform(m_rotationOffset); + offset.SetTranslation(m_positionOffset); + offset.MultiplyByScale(m_scaleOffset); + return offset; + } + + AZStd::vector EditorAttachmentComponent::GetTargetBoneOptions() const + { + AZStd::vector names; + + // insert blank entry, so user may choose to bind to NO bone. + names.push_back(""); + + // track whether currently-set bone is found + bool currentTargetBoneFound = false; + + // Get character and iterate over bones + AZ::u32 jointCount = 0; + LmbrCentral::SkeletalHierarchyRequestBus::EventResult(jointCount, m_targetId, &LmbrCentral::SkeletalHierarchyRequests::GetJointCount); + for (AZ::u32 jointIndex = 0; jointIndex < jointCount; ++jointIndex) + { + const char* name = nullptr; + LmbrCentral::SkeletalHierarchyRequestBus::EventResult(name, m_targetId, &LmbrCentral::SkeletalHierarchyRequests::GetJointNameByIndex, jointIndex); + if (name) + { + names.push_back(name); + + if (!currentTargetBoneFound) + { + currentTargetBoneFound = (m_targetBoneName == names.back()); + } + } + } + + // If we never found currently-set bone name, + // stick it at top of list, just in case user wants to keep it anyway + if (!currentTargetBoneFound && !m_targetBoneName.empty()) + { + names.insert(names.begin(), m_targetBoneName); + } + + return names; + } + + AZ::u32 EditorAttachmentComponent::OnTargetIdChanged() + { + // Warn about bad setups (it won't crash, but it's nice to handle this early) + if (m_targetId == GetEntityId()) + { + AZ_Warning(GetEntity()->GetName().c_str(), false, "AttachmentComponent cannot target self.") m_targetId.SetInvalid(); + } + + // Warn about children attaching to a parent + AZ::EntityId parentOfTarget; + AZ::TransformBus::EventResult(parentOfTarget, m_targetId, &AZ::TransformBus::Events::GetParentId); + while (parentOfTarget.IsValid()) + { + if (parentOfTarget == GetEntityId()) + { + AZ_Warning( + GetEntity()->GetName().c_str(), parentOfTarget != GetEntityId(), "AttachmentComponent cannot target child entity"); + m_targetId.SetInvalid(); + break; + } + + AZ::EntityId currentParentId = parentOfTarget; + parentOfTarget.SetInvalid(); + AZ::TransformBus::EventResult(parentOfTarget, currentParentId, &AZ::TransformBus::Events::GetParentId); + } + + AttachOrDetachAsNecessary(); + + return AZ::Edit::PropertyRefreshLevels::AttributesAndValues; // refresh bone options + } + + AZ::u32 EditorAttachmentComponent::OnTargetBoneChanged() + { + AttachOrDetachAsNecessary(); + return AZ::Edit::PropertyRefreshLevels::None; + } + + AZ::u32 EditorAttachmentComponent::OnTargetOffsetChanged() + { + EBUS_EVENT_ID(GetEntityId(), LmbrCentral::AttachmentComponentRequestBus, SetAttachmentOffset, GetTargetOffset()); + return AZ::Edit::PropertyRefreshLevels::None; + } + + AZ::u32 EditorAttachmentComponent::OnAttachedInitiallyChanged() + { + AttachOrDetachAsNecessary(); + return AZ::Edit::PropertyRefreshLevels::None; + } + + AZ::u32 EditorAttachmentComponent::OnScaleSourceChanged() + { + m_boneFollower.Deactivate(); + m_boneFollower.Activate(GetEntity(), CreateAttachmentConfiguration(), false); + return AZ::Edit::PropertyRefreshLevels::None; + } + + void EditorAttachmentComponent::AttachOrDetachAsNecessary() + { + if (m_attachedInitially && m_targetId.IsValid()) + { + EBUS_EVENT_ID( + GetEntityId(), LmbrCentral::AttachmentComponentRequestBus, Attach, m_targetId, m_targetBoneName.c_str(), GetTargetOffset()); + } + else + { + EBUS_EVENT_ID(GetEntityId(), LmbrCentral::AttachmentComponentRequestBus, Detach); + } + } + } // namespace Render + } // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.h new file mode 100644 index 0000000000..cac8a71a94 --- /dev/null +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Animation/EditorAttachmentComponent.h @@ -0,0 +1,104 @@ +/* +* 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 "AttachmentComponent.h" + +namespace AZ +{ + namespace Render + { + /*! + * In-editor attachment component. + * \ref AttachmentComponent + */ + class EditorAttachmentComponent + : public AzToolsFramework::Components::EditorComponentBase + { + private: + using Base = AzToolsFramework::Components::EditorComponentBase; + public: + AZ_COMPONENT(EditorAttachmentComponent, "{DA6072FD-E696-47D8-81D9-1F77D3464200}", Base); + static void Reflect(AZ::ReflectContext* context); + + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) + { + AttachmentComponent::GetProvidedServices(provided); + } + + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) + { + AttachmentComponent::GetIncompatibleServices(incompatible); + } + + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) + { + AttachmentComponent::GetRequiredServices(required); + } + + ~EditorAttachmentComponent() override = default; + void BuildGameEntity(AZ::Entity* gameEntity) override; + + protected: + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + ////////////////////////////////////////////////////////////////////////// + + AZ::u32 OnTargetIdChanged(); + AZ::u32 OnTargetBoneChanged(); + AZ::u32 OnTargetOffsetChanged(); + AZ::u32 OnAttachedInitiallyChanged(); + AZ::u32 OnScaleSourceChanged(); + + //! Invoked when an attachment property changes + void AttachOrDetachAsNecessary(); + + //! For populating ComboBox + AZStd::vector GetTargetBoneOptions() const; + + //! Create runtime configuration from editor configuration + AttachmentConfiguration CreateAttachmentConfiguration() const; + + //! Create AZ::Transform from position and rotation + AZ::Transform GetTargetOffset() const; + + //! Attach to this entity. + AZ::EntityId m_targetId; + + //! Attach to this bone on target entity. + AZStd::string m_targetBoneName; + + //! Offset from target bone's position. + AZ::Vector3 m_positionOffset = AZ::Vector3::CreateZero(); + + //! Offset from target bone's rotation. + AZ::Vector3 m_rotationOffset = AZ::Vector3::CreateZero(); + + //! Offset from target entity's scale. + AZ::Vector3 m_scaleOffset = AZ::Vector3::CreateOne(); + + //! Observe scale information from the specified source. + AttachmentConfiguration::ScaleSource m_scaleSource = AttachmentConfiguration::ScaleSource::WorldScale; + + //! Whether to attach to target upon activation. + //! If false, the entity remains detached until Attach() is called. + bool m_attachedInitially = true; + + //! Implements actual attachment functionality + AZ::Render::BoneFollower m_boneFollower; + }; + } // namespace Render +} // namespace AZ diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp index b33dd7f165..2ef4e1e229 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/Module.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR #include @@ -69,6 +70,7 @@ #include #include #include +#include #endif namespace AZ @@ -111,6 +113,7 @@ namespace AZ DiffuseProbeGridComponent::CreateDescriptor(), DeferredFogComponent::CreateDescriptor(), SurfaceData::SurfaceDataMeshComponent::CreateDescriptor(), + AttachmentComponent::CreateDescriptor(), #ifdef ATOMLYINTEGRATION_FEATURE_COMMON_EDITOR EditorAreaLightComponent::CreateDescriptor(), @@ -141,6 +144,7 @@ namespace AZ EditorDiffuseProbeGridComponent::CreateDescriptor(), EditorDeferredFogComponent::CreateDescriptor(), SurfaceData::EditorSurfaceDataMeshComponent::CreateDescriptor(), + EditorAttachmentComponent::CreateDescriptor(), #endif }); } diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake index ff8f33e06e..e58f72a121 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_editor_files.cmake @@ -11,6 +11,8 @@ set(FILES Source/Module.cpp + Source/Animation/EditorAttachmentComponent.h + Source/Animation/EditorAttachmentComponent.cpp Include/AtomLyIntegration/CommonFeatures/Material/EditorMaterialSystemComponentRequestBus.h Include/AtomLyIntegration/CommonFeatures/ReflectionProbe/EditorReflectionProbeBus.h Source/EditorCommonFeaturesSystemComponent.h diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake index b26ebc60a6..e13d1d37d6 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/atomlyintegration_commonfeatures_files.cmake @@ -10,6 +10,8 @@ # set(FILES + Source/Animation/AttachmentComponent.h + Source/Animation/AttachmentComponent.cpp Source/CoreLights/AreaLightComponent.h Source/CoreLights/AreaLightComponent.cpp Source/CoreLights/AreaLightComponentConfig.cpp diff --git a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h index b31091681e..1002fcbde1 100644 --- a/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h +++ b/Gems/AtomLyIntegration/EMotionFXAtom/Code/Source/AtomActorInstance.h @@ -18,7 +18,7 @@ #include -#include +#include #include #include diff --git a/Gems/CMakeLists.txt b/Gems/CMakeLists.txt index b6bda8c16e..3b630cfd2f 100644 --- a/Gems/CMakeLists.txt +++ b/Gems/CMakeLists.txt @@ -37,7 +37,6 @@ add_subdirectory(MessagePopup) add_subdirectory(PhysX) add_subdirectory(PhysXDebug) add_subdirectory(ScriptEvents) -add_subdirectory(Visibility) add_subdirectory(AssetValidation) add_subdirectory(VirtualGamepad) add_subdirectory(SaveData) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionInstancePool.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionInstancePool.cpp index cbe13308d9..d715fabd1c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionInstancePool.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionInstancePool.cpp @@ -220,7 +220,7 @@ namespace EMotionFX //mPool->mFreeList.Reserve( numInstances * 2 ); if (mPool->mFreeList.GetMaxLength() < mPool->mNumInstances) { - mPool->mFreeList.Reserve(mPool->mNumInstances); + mPool->mFreeList.Reserve(mPool->mNumInstances + mPool->mFreeList.GetMaxLength() / 2); } mPool->mFreeList.ResizeFast(startIndex + numInstances); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h index 85fc9c8d56..e33a5f3f51 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioPlugin.h @@ -78,8 +78,6 @@ namespace EMStudio virtual void OnBeforeRemovePlugin(uint32 classID) { MCORE_UNUSED(classID); } virtual void OnMainWindowClosed() {} - virtual void RegisterKeyboardShortcuts() {} - struct RenderInfo { MCORE_MEMORYOBJECTCATEGORY(EMStudioPlugin::RenderInfo, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_EMSTUDIOSDK) diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.cpp index b8093d2115..d6fdb9128b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.cpp @@ -116,14 +116,6 @@ namespace EMStudio } - void KeyboardShortcutsWindow::hideEvent(QHideEvent* event) - { - MCORE_UNUSED(event); - //if (mShortcutReceiverDialog) - // mShortcutReceiverDialog->reject(); - } - - // reconstruct the whole interface void KeyboardShortcutsWindow::ReInit() { @@ -138,11 +130,11 @@ namespace EMStudio // add the groups to the left list widget MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - const uint32 numGroups = shortcutManager->GetNumGroups(); + const size_t numGroups = shortcutManager->GetNumGroups(); for (uint32 i = 0; i < numGroups; ++i) { MysticQt::KeyboardShortcutManager::Group* group = shortcutManager->GetGroup(i); - mListWidget->addItem(group->GetName()); + mListWidget->addItem(FromStdString(group->GetName())); } mTableWidget->blockSignals(false); @@ -183,10 +175,10 @@ namespace EMStudio // get access to the shortcut group and some data MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); MysticQt::KeyboardShortcutManager::Group* group = shortcutManager->GetGroup(mSelectedGroup); - const uint32 numActions = group->GetNumActions(); + const size_t numActions = group->GetNumActions(); // set the row count - mTableWidget->setRowCount(numActions); + mTableWidget->setRowCount(aznumeric_caster(numActions)); // fill the table with the media root folders for (uint32 i = 0; i < numActions; ++i) @@ -195,11 +187,11 @@ namespace EMStudio MysticQt::KeyboardShortcutManager::Action* action = group->GetAction(i); // add the item to the table and set the row height - QTableWidgetItem* item = new QTableWidgetItem(action->mName.c_str()); + QTableWidgetItem* item = new QTableWidgetItem(action->m_qaction->text()); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); mTableWidget->setItem(i, 0, item); - const QString keyText = ConstructStringFromShortcut(action->mKey, action->mCtrl, action->mAlt); + const QString keyText = ConstructStringFromShortcut(action->m_qaction->shortcut()); item = new QTableWidgetItem(keyText); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); @@ -255,18 +247,14 @@ namespace EMStudio // handle conflicts if (shortcutWindow.mConflictDetected) { - shortcutWindow.mConflictAction->mKey = -1; - shortcutWindow.mConflictAction->mCtrl = false; - shortcutWindow.mConflictAction->mAlt = false; + shortcutWindow.mConflictAction->m_qaction->setShortcut({}); } // adjust the shortcut action - action->mKey = shortcutWindow.mKey; - action->mAlt = shortcutWindow.mAlt; - action->mCtrl = shortcutWindow.mCtrl; + action->m_qaction->setShortcut(shortcutWindow.mKey); // save the new shortcuts - QSettings settings(AZStd::string(GetManager()->GetAppDataFolder() + "EMStudioKeyboardShortcuts.cfg").c_str(), QSettings::IniFormat, this); + QSettings settings(FromStdString(AZStd::string(GetManager()->GetAppDataFolder() + "EMStudioKeyboardShortcuts.cfg")), QSettings::IniFormat, this); shortcutManager->Save(&settings); // reinit the window @@ -277,31 +265,14 @@ namespace EMStudio // construct a text version of a shortcut - QString KeyboardShortcutsWindow::ConstructStringFromShortcut(int key, bool ctrl, bool alt) + QString KeyboardShortcutsWindow::ConstructStringFromShortcut(QKeySequence key) { - if (key == -1) + if (key.isEmpty()) { return "not set"; } - QString keyText; - - if (ctrl) - { - #if AZ_TRAIT_OS_PLATFORM_APPLE - keyText += "COMMAND + "; - #else - keyText += "CTRL + "; - #endif - } - if (alt) - { - keyText += "ALT + "; - } - - keyText += QKeySequence(key).toString(QKeySequence::NativeText); - - return keyText; + return key.toString(QKeySequence::NativeText); } @@ -313,9 +284,7 @@ namespace EMStudio return; } - mContextMenuAction->mKey = mContextMenuAction->mDefaultKey; - mContextMenuAction->mCtrl = mContextMenuAction->mDefaultCtrl; - mContextMenuAction->mAlt = mContextMenuAction->mDefaultAlt; + mContextMenuAction->m_qaction->setShortcut(mContextMenuAction->m_defaultKeySequence); ReInit(); } @@ -378,19 +347,14 @@ namespace EMStudio setWindowTitle(" "); layout->addWidget(new QLabel("Press the new shortcut on the keyboard:")); - // find the initial shortcut - //MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - mOrgAction = action; mOrgGroup = group; mConflictAction = nullptr; mConflictDetected = false; - mKey = action->mKey; - mCtrl = action->mCtrl; - mAlt = action->mAlt; + mKey = action->m_qaction->shortcut(); - QString keyText = KeyboardShortcutsWindow::ConstructStringFromShortcut(mKey, mCtrl, mAlt); + QString keyText = KeyboardShortcutsWindow::ConstructStringFromShortcut(mKey); mLabel = new QLabel(keyText); mLabel->setAlignment(Qt::AlignHCenter); @@ -431,9 +395,7 @@ namespace EMStudio // reset the shortcut to its default value void ShortcutReceiverDialog::ResetToDefault() { - mKey = mOrgAction->mDefaultKey; - mCtrl = mOrgAction->mDefaultCtrl; - mAlt = mOrgAction->mDefaultAlt; + mKey = mOrgAction->m_defaultKeySequence; UpdateInterface(); } @@ -444,10 +406,8 @@ namespace EMStudio { MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - QString keyText = KeyboardShortcutsWindow::ConstructStringFromShortcut(mKey, mCtrl, mAlt); - // check if the currently assigned shortcut is already taken by another shortcut - mConflictAction = shortcutManager->FindShortcut(mKey, mCtrl, mAlt, mOrgGroup); + mConflictAction = shortcutManager->FindShortcut(mKey, mOrgGroup); if (mConflictAction == nullptr || mConflictAction == mOrgAction) { mOKButton->setToolTip(""); @@ -465,39 +425,25 @@ namespace EMStudio if (mConflictAction) { - AZStd::string tempString; - - tempString = AZStd::string::format("Assigning new shortcut will unassign '%s' automatically.", mConflictAction->mName.c_str()); - mOKButton->setToolTip(tempString.c_str()); + mOKButton->setToolTip(QString("Assigning new shortcut will unassign '%1' automatically.").arg(mConflictAction->m_qaction->text())); MysticQt::KeyboardShortcutManager::Group* conflictGroup = shortcutManager->FindGroupForShortcut(mConflictAction); if (conflictGroup) { - tempString = AZStd::string::format("Conflicts with: %s -> %s", conflictGroup->GetName(), mConflictAction->mName.c_str()); + mConflictKeyLabel->setText(QString("Conflicts with: %1 -> %2").arg(FromStdString(conflictGroup->GetName())).arg(mConflictAction->m_qaction->text())); } else { - tempString = AZStd::string::format("Conflicts with: %s", mConflictAction->mName.c_str()); + mConflictKeyLabel->setText(QString("Conflicts with: %1").arg(mConflictAction->m_qaction->text())); } - - mConflictKeyLabel->setText(tempString.c_str()); } } // adjust the label text to the new shortcut + const QString keyText = KeyboardShortcutsWindow::ConstructStringFromShortcut(mKey); mLabel->setText(keyText); } - - // close dialog as soon as it lost focus - void ShortcutReceiverDialog::focusOutEvent(QFocusEvent* event) - { - MCORE_UNUSED(event); - // if (event->reason() == Qt::ActiveWindowFocusReason) - // reject(); - } - - // called when the user pressed a new shortcut void ShortcutReceiverDialog::keyPressEvent(QKeyEvent* event) { @@ -513,18 +459,12 @@ namespace EMStudio if (event->key() == Qt::Key_Escape) { - //mKey = mOrgAction->mKey; - //mCtrl = mOrgAction->mCtrl; - //mAlt = mOrgAction->mAlt; - // close the dialog when pressing ESC reject(); } else { - mKey = event->key(); - mCtrl = event->modifiers() & Qt::ControlModifier; - mAlt = event->modifiers() & Qt::AltModifier; + mKey = event->key() | event->modifiers(); } UpdateInterface(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.h index 024479cc90..f6d4f43642 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/KeyboardShortcutsWindow.h @@ -41,12 +41,9 @@ namespace EMStudio virtual ~ShortcutReceiverDialog() {} void keyPressEvent(QKeyEvent* event) override; - void focusOutEvent(QFocusEvent* event) override; void UpdateInterface(); - int mKey; - bool mCtrl; - bool mAlt; + QKeySequence mKey; bool mConflictDetected; MysticQt::KeyboardShortcutManager::Action* mConflictAction; @@ -74,7 +71,7 @@ namespace EMStudio void Init(); void ReInit(); - static QString ConstructStringFromShortcut(int key, bool ctrl, bool alt); + static QString ConstructStringFromShortcut(QKeySequence key); MysticQt::KeyboardShortcutManager::Group* GetCurrentGroup() const; void setVisible(bool visible) override; @@ -95,6 +92,5 @@ namespace EMStudio ShortcutReceiverDialog* mShortcutReceiverDialog; void contextMenuEvent(QContextMenuEvent* event) override; - void hideEvent(QHideEvent* event) override; }; } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp index 496b6b8e94..950b63ff26 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.cpp @@ -66,6 +66,7 @@ #include #include #include +#include AZ_PUSH_DISABLE_WARNING(4267, "-Wconversion") #include AZ_POP_DISABLE_WARNING @@ -508,14 +509,33 @@ namespace EMStudio mShortcutManager = new MysticQt::KeyboardShortcutManager(); // load the old shortcuts - QSettings shortcutSettings(AZStd::string(GetManager()->GetAppDataFolder() + "EMStudioKeyboardShortcuts.cfg").c_str(), QSettings::IniFormat, this); - mShortcutManager->Load(&shortcutSettings); + LoadKeyboardShortcuts(); // add the application mode group - const char* layoutGroupName = "Layouts"; - mShortcutManager->RegisterKeyboardShortcut("AnimGraph", layoutGroupName, Qt::Key_1, false, true, false); - mShortcutManager->RegisterKeyboardShortcut("Animation", layoutGroupName, Qt::Key_2, false, true, false); - mShortcutManager->RegisterKeyboardShortcut("Character", layoutGroupName, Qt::Key_3, false, true, false); + constexpr AZStd::string_view layoutGroupName = "Layouts"; + QAction* animGraphLayoutAction = new QAction( + "AnimGraph", + this); + animGraphLayoutAction->setShortcut(Qt::Key_1 | Qt::AltModifier); + mShortcutManager->RegisterKeyboardShortcut(animGraphLayoutAction, layoutGroupName, false); + connect(animGraphLayoutAction, &QAction::triggered, [this]{ mApplicationMode->setCurrentIndex(0); }); + addAction(animGraphLayoutAction); + + QAction* animationLayoutAction = new QAction( + "Animation", + this); + animationLayoutAction->setShortcut(Qt::Key_2 | Qt::AltModifier); + mShortcutManager->RegisterKeyboardShortcut(animationLayoutAction, layoutGroupName, false); + connect(animationLayoutAction, &QAction::triggered, [this]{ mApplicationMode->setCurrentIndex(1); }); + addAction(animationLayoutAction); + + QAction* characterLayoutAction = new QAction( + "Character", + this); + characterLayoutAction->setShortcut(Qt::Key_1 | Qt::AltModifier); + mShortcutManager->RegisterKeyboardShortcut(characterLayoutAction, layoutGroupName, false); + connect(characterLayoutAction, &QAction::triggered, [this]{ mApplicationMode->setCurrentIndex(2); }); + addAction(characterLayoutAction); EMotionFX::ActorEditorRequestBus::Handler::BusConnect(); @@ -1267,6 +1287,12 @@ namespace EMStudio mRecentActors.AddRecentFile(fileName.toUtf8().data()); } + void MainWindow::LoadKeyboardShortcuts() + { + QSettings shortcutSettings(AZStd::string(GetManager()->GetAppDataFolder() + "EMStudioKeyboardShortcuts.cfg").c_str(), QSettings::IniFormat, this); + mShortcutManager->Load(&shortcutSettings); + } + void MainWindow::LoadActor(const char* fileName, bool replaceCurrentScene) { // create the final command @@ -2577,41 +2603,6 @@ namespace EMStudio QTimer::singleShot(0, this, &MainWindow::RaiseFloatingWidgets); } - void MainWindow::keyPressEvent(QKeyEvent* event) - { - const char* layoutGroupName = "Layouts"; - const uint32 numLayouts = GetMainWindow()->GetNumLayouts(); - for (uint32 i = 0; i < numLayouts; ++i) - { - if (mShortcutManager->Check(event, GetLayoutName(i), layoutGroupName)) - { - mApplicationMode->setCurrentIndex(i); - event->accept(); - return; - } - } - - event->ignore(); - } - - - void MainWindow::keyReleaseEvent(QKeyEvent* event) - { - const char* layoutGroupName = "Layouts"; - const uint32 numLayouts = GetNumLayouts(); - for (uint32 i = 0; i < numLayouts; ++i) - { - if (mShortcutManager->Check(event, layoutGroupName, GetLayoutName(i))) - { - event->accept(); - return; - } - } - - event->ignore(); - } - - // get the name of the currently active layout const char* MainWindow::GetCurrentLayoutName() const { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h index 15edaef144..850715b23f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h @@ -152,9 +152,6 @@ namespace EMStudio FileManager* GetFileManager() const { return mFileManager; } PreferencesWindow* GetPreferencesWindow() const { return mPreferencesWindow; } - void keyPressEvent(QKeyEvent* event) override; - void keyReleaseEvent(QKeyEvent* event) override; - uint32 GetNumLayouts() const { return mLayoutNames.GetLength(); } const char* GetLayoutName(uint32 index) const { return mLayoutNames[index].c_str(); } const char* GetCurrentLayoutName() const; @@ -168,6 +165,8 @@ namespace EMStudio void AddRecentActorFile(const QString& fileName); + void LoadKeyboardShortcuts(); + public slots: void OnAutosaveTimeOut(); void LoadLayoutAfterShow(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/PluginManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/PluginManager.cpp index 214ed68367..ffe29ed691 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/PluginManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/PluginManager.cpp @@ -136,7 +136,6 @@ namespace EMStudio mActivePlugins.push_back(newPlugin); newPlugin->Init(); - newPlugin->RegisterKeyboardShortcuts(); return newPlugin; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp index 47b88b1fa2..8e4c1bce37 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.cpp @@ -1020,17 +1020,6 @@ namespace EMStudio } - // register keyboard shortcuts used for the render plugin - void RenderPlugin::RegisterKeyboardShortcuts() - { - MysticQt::KeyboardShortcutManager* shortcutManger = GetMainWindow()->GetShortcutManager(); - - shortcutManger->RegisterKeyboardShortcut("Show Selected", "Render Window", Qt::Key_S, false, false, true); - shortcutManger->RegisterKeyboardShortcut("Show Entire Scene", "Render Window", Qt::Key_A, false, false, true); - shortcutManger->RegisterKeyboardShortcut("Toggle Selection Box Rendering", "Render Window", Qt::Key_J, false, false, true); - } - - // find the trajectory path for a given actor instance MCommon::RenderUtil::TrajectoryTracePath* RenderPlugin::FindTracePath(EMotionFX::ActorInstance* actorInstance) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h index 43f237b89e..7dab0a5f95 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderPlugin.h @@ -124,9 +124,6 @@ namespace EMStudio void ViewCloseup(bool selectedInstancesOnly = true, RenderWidget* renderWidget = nullptr, float flightTime = DEFAULT_FLIGHT_TIME); void SetSkipFollowCalcs(bool skipFollowCalcs); - // keyboard shortcuts - void RegisterKeyboardShortcuts() override; - // manipulators void ReInitTransformationManipulators(); MCommon::TransformationManipulator* GetActiveManipulator(MCommon::Camera* camera, int32 mousePosX, int32 mousePosY); @@ -177,6 +174,11 @@ namespace EMStudio void SaveRenderOptions(); void LoadRenderOptions(); + inline static constexpr AZStd::string_view s_renderWindowShortcutGroupName = "Render Window"; + inline static constexpr AZStd::string_view s_showSelectedShortcutName = "Show Selected"; + inline static constexpr AZStd::string_view s_showEntireSceneShortcutName = "Show Entire Scene"; + inline static constexpr AZStd::string_view s_toggleSelectionBoxRenderingShortcutName = "Toggle Selection Box Rendering"; + public slots: void SetManipulatorMode(RenderOptions::ManipulatorMode mode); void SetSelectionMode() { SetManipulatorMode(RenderOptions::ManipulatorMode::SELECT); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp index f6c44980fe..9abb05ea2c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.cpp @@ -16,7 +16,9 @@ #include "../PreferencesWindow.h" #include #include +#include #include +#include #include @@ -156,8 +158,17 @@ namespace EMStudio cameraMenu->addSeparator(); cameraMenu->addAction("Reset Camera", [this]() { this->OnResetCamera(); }); - cameraMenu->addAction("Show Selected", this, &RenderViewWidget::OnShowSelected); - cameraMenu->addAction("Show Entire Scene", this, &RenderViewWidget::OnShowEntireScene); + + QAction* showSelectedAction = cameraMenu->addAction("Show Selected", this, &RenderViewWidget::OnShowSelected); + showSelectedAction->setShortcut(Qt::Key_S); + GetMainWindow()->GetShortcutManager()->RegisterKeyboardShortcut(showSelectedAction, RenderPlugin::s_renderWindowShortcutGroupName, true); + addAction(showSelectedAction); + + QAction* showEntireSceneAction = cameraMenu->addAction("Show Entire Scene", this, &RenderViewWidget::OnShowEntireScene); + showEntireSceneAction->setShortcut(Qt::Key_A); + GetMainWindow()->GetShortcutManager()->RegisterKeyboardShortcut(showEntireSceneAction, RenderPlugin::s_renderWindowShortcutGroupName, true); + addAction(showEntireSceneAction); + cameraMenu->addSeparator(); mFollowCharacterAction = cameraMenu->addAction(tr("Follow Character")); @@ -181,8 +192,30 @@ namespace EMStudio connect(m_manipulatorModes[RenderOptions::ROTATE], &QAction::triggered, mPlugin, &RenderPlugin::SetRotationMode); connect(m_manipulatorModes[RenderOptions::SCALE], &QAction::triggered, mPlugin, &RenderPlugin::SetScaleMode); + QAction* toggleSelectionBoxRendering = new QAction( + "Toggle Selection Box Rendering", + this + ); + toggleSelectionBoxRendering->setShortcut(Qt::Key_J); + GetMainWindow()->GetShortcutManager()->RegisterKeyboardShortcut(toggleSelectionBoxRendering, RenderPlugin::s_renderWindowShortcutGroupName, true); + connect(toggleSelectionBoxRendering, &QAction::triggered, this, [this] + { + mPlugin->GetRenderOptions()->SetRenderSelectionBox(mPlugin->GetRenderOptions()->GetRenderSelectionBox() ^ true); + }); + addAction(toggleSelectionBoxRendering); + + QAction* deleteSelectedActorInstance = new QAction( + "Delete Selected Actor Instance", + this + ); + deleteSelectedActorInstance->setShortcut(Qt::Key_Delete); + connect(deleteSelectedActorInstance, &QAction::triggered, []{ CommandSystem::RemoveSelectedActorInstances(); }); + addAction(deleteSelectedActorInstance); + Reset(); UpdateInterface(); + + GetMainWindow()->LoadKeyboardShortcuts(); } void RenderViewWidget::SetManipulatorMode(RenderOptions::ManipulatorMode mode) diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h index 33b648f9c9..3ef48d0749 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderViewWidget.h @@ -43,6 +43,8 @@ namespace EMStudio RenderViewWidget(RenderPlugin* parentPlugin, QWidget* parentWidget); virtual ~RenderViewWidget(); + void CreateActions(); + enum ERenderFlag { RENDER_SOLID = 0, diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.cpp index 6218194fc6..5ca912ef71 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.cpp @@ -25,7 +25,6 @@ #include "../EMStudioManager.h" #include "../MainWindow.h" #include -#include namespace EMStudio @@ -76,7 +75,6 @@ namespace EMStudio delete mAxisFakeCamera; } - // start view closeup flight void RenderWidget::ViewCloseup(const MCore::AABB& aabb, float flightTime, uint32 viewCloseupWaiting) { @@ -726,72 +724,6 @@ namespace EMStudio } - // called when a key got pressed - void RenderWidget::OnKeyPressEvent(QWidget* renderWidget, QKeyEvent* event) - { - MCORE_UNUSED(renderWidget); - MysticQt::KeyboardShortcutManager* shortcutManger = GetMainWindow()->GetShortcutManager(); - - if (shortcutManger->Check(event, "Show Selected", "Render Window")) - { - mPlugin->ViewCloseup(true, this); - event->accept(); - return; - } - - if (shortcutManger->Check(event, "Show Entire Scene", "Render Window")) - { - mPlugin->ViewCloseup(false, this); - event->accept(); - return; - } - - if (shortcutManger->Check(event, "Toggle Selection Box Rendering", "Render Window")) - { - mPlugin->GetRenderOptions()->SetRenderSelectionBox(mPlugin->GetRenderOptions()->GetRenderSelectionBox() ^ true); - event->accept(); - return; - } - - if (event->key() == Qt::Key_Delete) - { - CommandSystem::RemoveSelectedActorInstances(); - event->accept(); - return; - } - - event->ignore(); - } - - - // called when a key got released - void RenderWidget::OnKeyReleaseEvent(QWidget* renderWidget, QKeyEvent* event) - { - MCORE_UNUSED(renderWidget); - MysticQt::KeyboardShortcutManager* shortcutManger = GetMainWindow()->GetShortcutManager(); - - if (shortcutManger->Check(event, "Show Selected", "Render Window")) - { - event->accept(); - return; - } - - if (shortcutManger->Check(event, "Show Entire Scene", "Render Window")) - { - event->accept(); - return; - } - - if (event->key() == Qt::Key_Delete) - { - event->accept(); - return; - } - - event->ignore(); - } - - // handles context menu events void RenderWidget::OnContextMenuEvent(QWidget* renderWidget, bool shiftPressed, bool altPressed, int32 localMouseX, int32 localMouseY, QPoint globalMousePos) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.h index f376f10f84..99c1c38f70 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/RenderPlugin/RenderWidget.h @@ -96,6 +96,8 @@ namespace EMStudio RenderWidget(RenderPlugin* renderPlugin, RenderViewWidget* viewWidget); virtual ~RenderWidget(); + void CreateActions(); + // main render callback virtual void Render() = 0; virtual void Update() = 0; @@ -132,8 +134,6 @@ namespace EMStudio void OnMousePressEvent(QWidget* renderWidget, QMouseEvent* event); void OnMouseReleaseEvent(QWidget* renderWidget, QMouseEvent* event); void OnWheelEvent(QWidget* renderWidget, QWheelEvent* event); - void OnKeyPressEvent(QWidget* renderWidget, QKeyEvent* event); - void OnKeyReleaseEvent(QWidget* renderWidget, QKeyEvent* event); void OnContextMenuEvent(QWidget* renderWidget, bool shiftPressed, bool altPressed, int32 localMouseX, int32 localMouseY, QPoint globalMousePos); protected: diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.h index 107869de33..c81d7c61ae 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/RenderPlugins/Source/OpenGLRender/GLWidget.h @@ -72,8 +72,6 @@ namespace EMStudio void mousePressEvent(QMouseEvent* event) { RenderWidget::OnMousePressEvent(this, event); } void mouseReleaseEvent(QMouseEvent* event) { RenderWidget::OnMouseReleaseEvent(this, event); } void wheelEvent(QWheelEvent* event) { RenderWidget::OnWheelEvent(this, event); } - void keyPressEvent(QKeyEvent* event) { RenderWidget::OnKeyPressEvent(this, event); } - void keyReleaseEvent(QKeyEvent* event) { RenderWidget::OnKeyReleaseEvent(this, event); } void focusInEvent(QFocusEvent* event); void focusOutEvent(QFocusEvent* event); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.cpp index 9cbd654393..f76f684ea5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.cpp @@ -99,7 +99,7 @@ namespace EMStudio } if (!m_pasteItems.empty()) { - m_pasteOperation = PasteOperation::Copy; + SetPasteOperation(PasteOperation::Copy); } } @@ -126,7 +126,7 @@ namespace EMStudio } if (!m_pasteItems.empty()) { - m_pasteOperation = PasteOperation::Cut; + SetPasteOperation(PasteOperation::Cut); } } @@ -168,8 +168,8 @@ namespace EMStudio } } - m_pasteOperation = PasteOperation::None; m_pasteItems.clear(); + SetPasteOperation(PasteOperation::None); } void AnimGraphActionManager::SetEntryState() @@ -443,6 +443,18 @@ namespace EMStudio } } + void AnimGraphActionManager::NavigateToParent() + { + const QModelIndex parentFocus = m_plugin->GetAnimGraphModel().GetParentFocus(); + if (parentFocus.isValid()) + { + QModelIndex newParentFocus = parentFocus.model()->parent(parentFocus); + if (newParentFocus.isValid()) + { + m_plugin->GetAnimGraphModel().Focus(newParentFocus); + } + } + } void AnimGraphActionManager::OpenReferencedAnimGraph(EMotionFX::AnimGraphReferenceNode* referenceNode) { @@ -678,4 +690,10 @@ namespace EMStudio GetCommandManager()->ExecuteCommandGroup(commandGroup, outResult); } } + + void AnimGraphActionManager::SetPasteOperation(PasteOperation newOperation) + { + m_pasteOperation = newOperation; + emit PasteStateChanged(); + } } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.h index 30b520d2a5..9182272875 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphActionManager.h @@ -72,6 +72,9 @@ namespace EMStudio Bottom }; + signals: + void PasteStateChanged(); + public slots: void Copy(); void Cut(); @@ -95,6 +98,7 @@ namespace EMStudio void DeleteSelectedNodes(); void NavigateToNode(); + void NavigateToParent(); void OpenReferencedAnimGraph(EMotionFX::AnimGraphReferenceNode* referenceNode); @@ -126,5 +130,7 @@ namespace EMStudio AnimGraphPlugin* m_plugin; AZStd::vector m_pasteItems; PasteOperation m_pasteOperation; + + void SetPasteOperation(PasteOperation newOperation); }; } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.cpp index 2669153dfd..d9b77ccf89 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.cpp @@ -461,10 +461,7 @@ namespace EMStudio { m_actionFilter = actionFilter; - if (mViewWidget) - { - mViewWidget->UpdateSelection(); - } + emit ActionFilterChanged(); } const AnimGraphActionFilter& AnimGraphPlugin::GetActionFilter() const @@ -1408,33 +1405,6 @@ namespace EMStudio } - // register keyboard shortcuts used for the render plugin - void AnimGraphPlugin::RegisterKeyboardShortcuts() - { - MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - - shortcutManager->RegisterKeyboardShortcut("Fit Entire Graph", "Anim Graph Window", Qt::Key_A, false, false, true); - shortcutManager->RegisterKeyboardShortcut("Zoom On Selected Nodes", "Anim Graph Window", Qt::Key_Z, false, false, true); - - shortcutManager->RegisterKeyboardShortcut("Open Parent Node", "Anim Graph Window", Qt::Key_Up, false, false, true); - shortcutManager->RegisterKeyboardShortcut("Open Selected Node", "Anim Graph Window", Qt::Key_Down, false, false, true); - shortcutManager->RegisterKeyboardShortcut("History Back", "Anim Graph Window", Qt::Key_Left, false, false, true); - shortcutManager->RegisterKeyboardShortcut("History Forward", "Anim Graph Window", Qt::Key_Right, false, false, true); - - shortcutManager->RegisterKeyboardShortcut("Align Left", "Anim Graph Window", Qt::Key_L, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Align Right", "Anim Graph Window", Qt::Key_R, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Align Top", "Anim Graph Window", Qt::Key_T, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Align Bottom", "Anim Graph Window", Qt::Key_B, true, false, true); - - shortcutManager->RegisterKeyboardShortcut("Cut", "Anim Graph Window", Qt::Key_X, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Copy", "Anim Graph Window", Qt::Key_C, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Paste", "Anim Graph Window", Qt::Key_V, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Select All", "Anim Graph Window", Qt::Key_A, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Unselect All", "Anim Graph Window", Qt::Key_D, true, false, true); - shortcutManager->RegisterKeyboardShortcut("Delete Selected Nodes", "Anim Graph Window", Qt::Key_Delete, false, false, true); - } - - // double clicked a node history item in the timeview plugin void AnimGraphPlugin::OnDoubleClickedRecorderNodeHistoryItem(EMotionFX::Recorder::ActorInstanceData* actorInstanceData, EMotionFX::Recorder::NodeHistoryItem* historyItem) { diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.h index c1e2004aae..cb8e015429 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/AnimGraphPlugin.h @@ -49,7 +49,6 @@ namespace EMotionFX class AnimGraphObjectFactory; } - namespace EMStudio { // forward declarations @@ -151,8 +150,6 @@ namespace EMStudio void LoadOptions(); void SaveOptions(); - void RegisterKeyboardShortcuts() override; - bool CheckIfCanCreateObject(EMotionFX::AnimGraphObject* parentObject, const EMotionFX::AnimGraphObject* object, EMotionFX::AnimGraphObject::ECategory category) const; void ProcessFrame(float timePassedInSeconds) override; @@ -171,6 +168,27 @@ namespace EMStudio /// Is the given anim graph running on any selected actor instance? bool IsAnimGraphActive(EMotionFX::AnimGraph* animGraph) const; + inline static constexpr AZStd::string_view s_animGraphWindowShortcutGroupName = "Anim Graph Window"; + inline static constexpr AZStd::string_view s_fitEntireGraphShortcutName = "Fit Entire Graph"; + inline static constexpr AZStd::string_view s_zoomOnSelectedNodesShortcutName = "Zoom On Selected Nodes"; + inline static constexpr AZStd::string_view s_openParentNodeShortcutName = "Open Parent Node"; + inline static constexpr AZStd::string_view s_openSelectedNodeShortcutName = "Open Selected Node"; + inline static constexpr AZStd::string_view s_historyBackShortcutName = "History Back"; + inline static constexpr AZStd::string_view s_historyForwardShortcutName = "History Forward"; + inline static constexpr AZStd::string_view s_alignLeftShortcutName = "Align Left"; + inline static constexpr AZStd::string_view s_alignRightShortcutName = "Align Right"; + inline static constexpr AZStd::string_view s_alignTopShortcutName = "Align Top"; + inline static constexpr AZStd::string_view s_alignBottomShortcutName = "Align Bottom"; + inline static constexpr AZStd::string_view s_cutShortcutName = "Cut"; + inline static constexpr AZStd::string_view s_copyShortcutName = "Copy"; + inline static constexpr AZStd::string_view s_pasteShortcutName = "Paste"; + inline static constexpr AZStd::string_view s_selectAllShortcutName = "Select All"; + inline static constexpr AZStd::string_view s_unselectAllShortcutName = "Unselect All"; + inline static constexpr AZStd::string_view s_deleteSelectedNodesShortcutName = "Delete Selected Nodes"; + + signals: + void ActionFilterChanged(); + public slots: void OnFileOpen(); void OnFileSave(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.cpp index 4203271b58..eccabd37b5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -40,74 +41,298 @@ namespace EMStudio : QWidget(parentWidget) , m_parentPlugin(plugin) { - for (uint32 i = 0; i < NUM_OPTIONS; ++i) + EMotionFX::ActorEditorRequestBus::Handler::BusConnect(); + } + + void BlendGraphViewWidget::CreateActions() + { + MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); + + m_actions[SELECTION_ALIGNLEFT] = new QAction( + QIcon(":/EMotionFX/AlignLeft.svg"), + FromStdString(AnimGraphPlugin::s_alignLeftShortcutName), + this); + m_actions[SELECTION_ALIGNLEFT]->setShortcut(Qt::Key_L | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_ALIGNLEFT], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_ALIGNLEFT], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignLeft); + + m_actions[SELECTION_ALIGNRIGHT] = new QAction( + QIcon(":/EMotionFX/AlignRight.svg"), + FromStdString(AnimGraphPlugin::s_alignRightShortcutName), + this); + m_actions[SELECTION_ALIGNRIGHT]->setShortcut(Qt::Key_R | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_ALIGNRIGHT], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_ALIGNRIGHT], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignRight); + + m_actions[SELECTION_ALIGNTOP] = new QAction( + QIcon(":/EMotionFX/AlignTop.svg"), + FromStdString(AnimGraphPlugin::s_alignTopShortcutName), + this); + m_actions[SELECTION_ALIGNTOP]->setShortcut(Qt::Key_T | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_ALIGNTOP], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_ALIGNTOP], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignTop); + + m_actions[SELECTION_ALIGNBOTTOM] = new QAction( + QIcon(":/EMotionFX/AlignBottom.svg"), + FromStdString(AnimGraphPlugin::s_alignBottomShortcutName), + this); + m_actions[SELECTION_ALIGNBOTTOM]->setShortcut(Qt::Key_B | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_ALIGNBOTTOM], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_ALIGNBOTTOM], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignBottom); + + m_actions[SELECTION_SELECTALL] = new QAction( + FromStdString(AnimGraphPlugin::s_selectAllShortcutName), + this + ); + m_actions[SELECTION_SELECTALL]->setShortcut(Qt::Key_A | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_SELECTALL], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_SELECTALL], &QAction::triggered, [this] + { + NodeGraph* activeGraph = m_parentPlugin->GetGraphWidget()->GetActiveGraph(); + if (activeGraph) + { + activeGraph->SelectAllNodes(); + } + }); + + m_actions[SELECTION_UNSELECTALL] = new QAction( + FromStdString(AnimGraphPlugin::s_unselectAllShortcutName), + this + ); + m_actions[SELECTION_UNSELECTALL]->setShortcut(Qt::Key_D | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[SELECTION_UNSELECTALL], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[SELECTION_UNSELECTALL], &QAction::triggered, [this] + { + NodeGraph* activeGraph = m_parentPlugin->GetGraphWidget()->GetActiveGraph(); + if (activeGraph) + { + activeGraph->UnselectAllNodes(); + } + }); + + m_actions[FILE_NEW] = new QAction( + QIcon(":/EMotionFX/Plus.svg"), + tr("Create a new anim graph"), + this); + m_actions[FILE_NEW]->setObjectName("EMFX.BlendGraphViewWidget.NewButton"); + connect(m_actions[FILE_NEW], &QAction::triggered, this, &BlendGraphViewWidget::OnCreateAnimGraph); + + m_actions[FILE_OPEN] = new QAction( + tr("Open..."), + this); + connect(m_actions[FILE_OPEN], &QAction::triggered, m_parentPlugin, &AnimGraphPlugin::OnFileOpen); + + m_actions[FILE_SAVE] = new QAction( + tr("Save"), + this); + connect(m_actions[FILE_SAVE], &QAction::triggered, m_parentPlugin, &AnimGraphPlugin::OnFileSave); + + m_actions[FILE_SAVEAS] = new QAction( + tr("Save as..."), + this); + connect(m_actions[FILE_SAVEAS], &QAction::triggered, m_parentPlugin, &AnimGraphPlugin::OnFileSaveAs); + + m_actions[NAVIGATION_FORWARD] = new QAction( + QIcon(":/EMotionFX/Forward.svg"), + FromStdString(AnimGraphPlugin::s_historyForwardShortcutName), + this); + m_actions[NAVIGATION_FORWARD]->setShortcut(Qt::Key_Right); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_FORWARD], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_FORWARD], &QAction::triggered, [this] + { + m_parentPlugin->GetNavigationHistory()->StepForward(); + UpdateNavigation(); + }); + + m_actions[NAVIGATION_BACK] = new QAction( + QIcon(":/EMotionFX/Backward.svg"), + FromStdString(AnimGraphPlugin::s_historyBackShortcutName), + this); + m_actions[NAVIGATION_BACK]->setShortcut(Qt::Key_Left); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_BACK], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_BACK], &QAction::triggered, [this] + { + m_parentPlugin->GetNavigationHistory()->StepBackward(); + UpdateNavigation(); + }); + + m_actions[NAVIGATION_NAVPANETOGGLE] = new QAction( + QIcon(":/EMotionFX/List.svg"), + tr("Show/hide navigation pane"), + this); + connect(m_actions[NAVIGATION_NAVPANETOGGLE], &QAction::triggered, this, &BlendGraphViewWidget::ToggleNavigationPane); + + m_actions[NAVIGATION_OPEN_SELECTED] = new QAction( + FromStdString(AnimGraphPlugin::s_openSelectedNodeShortcutName), + this); + m_actions[NAVIGATION_OPEN_SELECTED]->setShortcut(Qt::Key_Down); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_OPEN_SELECTED], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_OPEN_SELECTED], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::NavigateToNode); + + m_actions[NAVIGATION_TO_PARENT] = new QAction( + FromStdString(AnimGraphPlugin::s_openParentNodeShortcutName), + this); + m_actions[NAVIGATION_TO_PARENT]->setShortcut(Qt::Key_Up); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_TO_PARENT], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_TO_PARENT], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::NavigateToParent); + + m_actions[NAVIGATION_FRAME_ALL] = new QAction( + QIcon(":/EMotionFX/ZoomSelected.svg"), + FromStdString(AnimGraphPlugin::s_fitEntireGraphShortcutName), + this); + m_actions[NAVIGATION_FRAME_ALL]->setShortcut(Qt::Key_A); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_FRAME_ALL], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_FRAME_ALL], &QAction::triggered, this, &BlendGraphViewWidget::ZoomToAll); + + m_actions[NAVIGATION_ZOOMSELECTION] = new QAction( + QIcon(":/EMotionFX/ZoomSelected.svg"), + FromStdString(AnimGraphPlugin::s_zoomOnSelectedNodesShortcutName), + this); + m_actions[NAVIGATION_ZOOMSELECTION]->setShortcut(Qt::Key_Z); + shortcutManager->RegisterKeyboardShortcut(m_actions[NAVIGATION_ZOOMSELECTION], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[NAVIGATION_ZOOMSELECTION], &QAction::triggered, this, &BlendGraphViewWidget::ZoomSelected); + + m_actions[ACTIVATE_ANIMGRAPH] = new QAction( + QIcon(":/EMotionFX/PlayForward.svg"), + tr("Activate Animgraph/State"), + this); + connect(m_actions[ACTIVATE_ANIMGRAPH], &QAction::triggered, &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::ActivateAnimGraph); + + m_actions[VISUALIZATION_PLAYSPEEDS] = new QAction( + tr("Display Play Speeds"), + this); + m_actions[VISUALIZATION_PLAYSPEEDS]->setCheckable(true); + connect(m_actions[VISUALIZATION_PLAYSPEEDS], &QAction::triggered, this, &BlendGraphViewWidget::OnDisplayPlaySpeeds); + + m_actions[VISUALIZATION_GLOBALWEIGHTS] = new QAction( + tr("Display Global Weights"), + this); + m_actions[VISUALIZATION_GLOBALWEIGHTS]->setCheckable(true); + connect(m_actions[VISUALIZATION_GLOBALWEIGHTS], &QAction::triggered, this, &BlendGraphViewWidget::OnDisplayGlobalWeights); + + m_actions[VISUALIZATION_SYNCSTATUS] = new QAction( + tr("Display Sync Status"), + this); + m_actions[VISUALIZATION_SYNCSTATUS]->setCheckable(true); + connect(m_actions[VISUALIZATION_SYNCSTATUS], &QAction::triggered, this, &BlendGraphViewWidget::OnDisplaySyncStatus); + + m_actions[VISUALIZATION_PLAYPOSITIONS] = new QAction( + tr("Display Play Positions"), + this); + m_actions[VISUALIZATION_PLAYPOSITIONS]->setCheckable(true); + connect(m_actions[VISUALIZATION_PLAYPOSITIONS], &QAction::triggered, this, &BlendGraphViewWidget::OnDisplayPlayPositions); + + m_actions[EDIT_CUT] = new QAction( + FromStdString(AnimGraphPlugin::s_cutShortcutName), + this + ); + m_actions[EDIT_CUT]->setShortcut(Qt::Key_X | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[EDIT_CUT], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[EDIT_CUT], &QAction::triggered, this, [this] + { + m_parentPlugin->GetActionManager().Cut(); + }); + + m_actions[EDIT_COPY] = new QAction( + FromStdString(AnimGraphPlugin::s_copyShortcutName), + this + ); + m_actions[EDIT_COPY]->setShortcut(Qt::Key_C | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[EDIT_COPY], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[EDIT_COPY], &QAction::triggered, this, [this] + { + m_parentPlugin->GetActionManager().Copy(); + }); + + m_actions[EDIT_PASTE] = new QAction( + FromStdString(AnimGraphPlugin::s_pasteShortcutName), + this + ); + m_actions[EDIT_PASTE]->setShortcut(Qt::Key_V | Qt::ControlModifier); + shortcutManager->RegisterKeyboardShortcut(m_actions[EDIT_PASTE], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[EDIT_PASTE], &QAction::triggered, this, [this] + { + const BlendGraphWidget* graphWidget = m_parentPlugin->GetGraphWidget(); + const NodeGraph* activeGraph = graphWidget->GetActiveGraph(); + if (!activeGraph) + { + return; + } + const QPoint pastePosition = graphWidget->underMouse() + ? graphWidget->SnapLocalToGrid(graphWidget->LocalToGlobal(graphWidget->mapFromGlobal(QCursor::pos()))) + : graphWidget->SnapLocalToGrid(graphWidget->LocalToGlobal(graphWidget->rect().center())); + m_parentPlugin->GetActionManager().Paste(activeGraph->GetModelIndex(), pastePosition); + }); + + m_actions[EDIT_DELETE] = new QAction( + FromStdString(AnimGraphPlugin::s_deleteSelectedNodesShortcutName), + this + ); + m_actions[EDIT_DELETE]->setShortcut(Qt::Key_Delete); + shortcutManager->RegisterKeyboardShortcut(m_actions[EDIT_DELETE], AnimGraphPlugin::s_animGraphWindowShortcutGroupName, true); + connect(m_actions[EDIT_DELETE], &QAction::triggered, this, [this] { - m_actions[i] = nullptr; + m_parentPlugin->GetGraphWidget()->DeleteSelectedItems(); + }); + + for (QAction* action : m_actions) + { + addAction(action); } - EMotionFX::ActorEditorRequestBus::Handler::BusConnect(); + GetMainWindow()->LoadKeyboardShortcuts(); } QToolBar* BlendGraphViewWidget::CreateTopToolBar() { QToolBar* toolBar = new QToolBar(this); toolBar->setObjectName("EMFX.BlendGraphViewWidget.TopToolBar"); - // Create new anim graph - { - QAction* action = toolBar->addAction(QIcon(":/EMotionFX/Plus.svg"), - tr("Create a new anim graph"), - this, &BlendGraphViewWidget::OnCreateAnimGraph); - action->setObjectName("EMFX.BlendGraphViewWidget.NewButton"); - - //action->setShortcut(QKeySequence::New); - m_actions[FILE_NEW] = action; - } + + toolBar->addAction(m_actions[FILE_NEW]); // Open anim graph { - QAction* action = toolBar->addAction( + m_openMenu = new QMenu(this); + connect(m_openMenu, &QMenu::aboutToShow, this, &BlendGraphViewWidget::BuildOpenMenu); + + QAction* action = new QAction( QIcon(":/EMotionFX/Open.svg"), - tr("Open anim graph asset")); - m_actions[FILE_OPEN] = action; + tr("Open")); + action->setMenu(m_openMenu); - QToolButton* toolButton = qobject_cast(toolBar->widgetForAction(action)); - AZ_Assert(toolButton, "The action widget must be a tool button."); - toolButton->setPopupMode(QToolButton::InstantPopup); + QToolButton* button = new QToolButton(); + button->setDefaultAction(action); + button->setPopupMode(QToolButton::InstantPopup); - m_openMenu = new QMenu(toolBar); - action->setMenu(m_openMenu); - BuildOpenMenu(); - connect(m_openMenu, &QMenu::aboutToShow, this, &BlendGraphViewWidget::BuildOpenMenu); + toolBar->addWidget(button); } + // Save anim graph { - QAction* saveMenuAction = toolBar->addAction( + QMenu* contextMenu = new QMenu(toolBar); + contextMenu->addAction(m_actions[FILE_SAVE]); + contextMenu->addAction(m_actions[FILE_SAVEAS]); + + QAction* saveMenuAction = new QAction( QIcon(":/EMotionFX/Save.svg"), tr("Save anim graph")); + saveMenuAction->setMenu(contextMenu); - QToolButton* toolButton = qobject_cast(toolBar->widgetForAction(saveMenuAction)); - AZ_Assert(toolButton, "The action widget must be a tool button."); - toolButton->setPopupMode(QToolButton::InstantPopup); - - QMenu* contextMenu = new QMenu(toolBar); - - m_actions[FILE_SAVE] = contextMenu->addAction(tr("Save"), m_parentPlugin, &AnimGraphPlugin::OnFileSave); - m_actions[FILE_SAVEAS] = contextMenu->addAction(tr("Save as..."), m_parentPlugin, &AnimGraphPlugin::OnFileSaveAs); + QToolButton* button = new QToolButton(); + button->setDefaultAction(saveMenuAction); + button->setPopupMode(QToolButton::InstantPopup); - saveMenuAction->setMenu(contextMenu); + toolBar->addWidget(button); } toolBar->addSeparator(); - m_actions[ACTIVATE_ANIMGRAPH] = toolBar->addAction(QIcon(":/EMotionFX/PlayForward.svg"), - tr("Activate Animgraph/State"), - &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::ActivateAnimGraph); + toolBar->addAction(m_actions[ACTIVATE_ANIMGRAPH]); + toolBar->addSeparator(); - m_actions[SELECTION_ZOOMSELECTION] = toolBar->addAction(QIcon(":/EMotionFX/ZoomSelected.svg"), - tr("Zoom Selection"), - this, &BlendGraphViewWidget::ZoomSelected); + toolBar->addAction(m_actions[NAVIGATION_ZOOMSELECTION]); // Visualization options { @@ -121,15 +346,10 @@ namespace EMStudio QMenu* contextMenu = new QMenu(toolBar); - m_actions[VISUALIZATION_PLAYSPEEDS] = contextMenu->addAction(tr("Display Play Speeds"), this, &BlendGraphViewWidget::OnDisplayPlaySpeeds); - m_actions[VISUALIZATION_GLOBALWEIGHTS] = contextMenu->addAction(tr("Display Global Weights"), this, &BlendGraphViewWidget::OnDisplayGlobalWeights); - m_actions[VISUALIZATION_SYNCSTATUS] = contextMenu->addAction(tr("Display Sync Status"), this, &BlendGraphViewWidget::OnDisplaySyncStatus); - m_actions[VISUALIZATION_PLAYPOSITIONS] = contextMenu->addAction(tr("Display Play Positions"), this, &BlendGraphViewWidget::OnDisplayPlayPositions); - - m_actions[VISUALIZATION_PLAYSPEEDS]->setCheckable(true); - m_actions[VISUALIZATION_GLOBALWEIGHTS]->setCheckable(true); - m_actions[VISUALIZATION_SYNCSTATUS]->setCheckable(true); - m_actions[VISUALIZATION_PLAYPOSITIONS]->setCheckable(true); + contextMenu->addAction(m_actions[VISUALIZATION_PLAYSPEEDS]); + contextMenu->addAction(m_actions[VISUALIZATION_GLOBALWEIGHTS]); + contextMenu->addAction(m_actions[VISUALIZATION_SYNCSTATUS]); + contextMenu->addAction(m_actions[VISUALIZATION_PLAYPOSITIONS]); menuAction->setMenu(contextMenu); } @@ -137,21 +357,10 @@ namespace EMStudio toolBar->addSeparator(); // Alignment Options - m_actions[SELECTION_ALIGNLEFT] = toolBar->addAction(QIcon(":/EMotionFX/AlignLeft.svg"), - tr("Align left"), - &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignLeft); - - m_actions[SELECTION_ALIGNRIGHT] = toolBar->addAction(QIcon(":/EMotionFX/AlignRight.svg"), - tr("Align right"), - &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignRight); - - m_actions[SELECTION_ALIGNTOP] = toolBar->addAction(QIcon(":/EMotionFX/AlignTop.svg"), - tr("Align top"), - &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignTop); - - m_actions[SELECTION_ALIGNBOTTOM] = toolBar->addAction(QIcon(":/EMotionFX/AlignBottom.svg"), - tr("Align bottom"), - &m_parentPlugin->GetActionManager(), &AnimGraphActionManager::AlignBottom); + toolBar->addAction(m_actions[SELECTION_ALIGNLEFT]); + toolBar->addAction(m_actions[SELECTION_ALIGNRIGHT]); + toolBar->addAction(m_actions[SELECTION_ALIGNTOP]); + toolBar->addAction(m_actions[SELECTION_ALIGNBOTTOM]); return toolBar; } @@ -160,27 +369,15 @@ namespace EMStudio { QToolBar* toolBar = new QToolBar(this); - m_actions[NAVIGATION_BACK] = toolBar->addAction(QIcon(":/EMotionFX/Backward.svg"), - tr("Back"), - this, [=] { - m_parentPlugin->GetNavigationHistory()->StepBackward(); - UpdateNavigation(); - }); + toolBar->addAction(m_actions[NAVIGATION_BACK]); - m_actions[NAVIGATION_FORWARD] = toolBar->addAction(QIcon(":/EMotionFX/Forward.svg"), - tr("Forward"), - this, [=] { - m_parentPlugin->GetNavigationHistory()->StepForward(); - UpdateNavigation(); - }); + toolBar->addAction(m_actions[NAVIGATION_FORWARD]); mNavigationLink = new NavigationLinkWidget(m_parentPlugin, this); mNavigationLink->setMinimumHeight(28); toolBar->addWidget(mNavigationLink); - m_actions[NAVIGATION_NAVPANETOGGLE] = toolBar->addAction(QIcon(":/EMotionFX/List.svg"), - tr("Show/hide navigation pane"), - this, &BlendGraphViewWidget::ToggleNavigationPane); + toolBar->addAction(m_actions[NAVIGATION_NAVPANETOGGLE]); return toolBar; } @@ -188,8 +385,11 @@ namespace EMStudio void BlendGraphViewWidget::Init(BlendGraphWidget* blendGraphWidget) { connect(&m_parentPlugin->GetAnimGraphModel(), &AnimGraphModel::FocusChanged, this, &BlendGraphViewWidget::OnFocusChanged); - connect(&m_parentPlugin->GetAnimGraphModel().GetSelectionModel(), &QItemSelectionModel::selectionChanged, this, &BlendGraphViewWidget::UpdateSelection); + connect(&m_parentPlugin->GetAnimGraphModel().GetSelectionModel(), &QItemSelectionModel::selectionChanged, this, &BlendGraphViewWidget::UpdateEnabledActions); connect(m_parentPlugin->GetNavigationHistory(), &NavigationHistory::ChangedSteppingLimits, this, &BlendGraphViewWidget::UpdateNavigation); + connect(m_parentPlugin->GetGraphWidget(), &NodeGraphWidget::ActiveGraphChanged, this, &BlendGraphViewWidget::UpdateEnabledActions); + connect(m_parentPlugin, &AnimGraphPlugin::ActionFilterChanged, this, &BlendGraphViewWidget::UpdateEnabledActions); + connect(&m_parentPlugin->GetActionManager(), &AnimGraphActionManager::PasteStateChanged, this, &BlendGraphViewWidget::UpdateEnabledActions); // create the vertical layout with the menu and the graph widget as entries QVBoxLayout* verticalLayout = new QVBoxLayout(this); @@ -198,6 +398,7 @@ namespace EMStudio verticalLayout->setMargin(2); // Create toolbars + CreateActions(); verticalLayout->addWidget(CreateTopToolBar()); verticalLayout->addWidget(CreateNavigationToolBar()); @@ -217,7 +418,7 @@ namespace EMStudio UpdateNavigation(); UpdateAnimGraphOptions(); - UpdateSelection(); + UpdateEnabledActions(); } BlendGraphViewWidget::~BlendGraphViewWidget() @@ -252,47 +453,35 @@ namespace EMStudio } } - void BlendGraphViewWidget::UpdateSelection() + void BlendGraphViewWidget::UpdateEnabledActions() { // do we have any selection? const bool anySelection = m_parentPlugin->GetAnimGraphModel().GetSelectionModel().hasSelection(); - SetOptionEnabled(SELECTION_ZOOMSELECTION, anySelection); - - QModelIndex firstSelectedNode; - bool atLeastTwoNodes = false; - const QModelIndexList selectedIndexes = m_parentPlugin->GetAnimGraphModel().GetSelectionModel().selectedRows(); - for (const QModelIndex& selected : selectedIndexes) - { - const AnimGraphModel::ModelItemType itemType = selected.data(AnimGraphModel::ROLE_MODEL_ITEM_TYPE).value(); - if (itemType == AnimGraphModel::ModelItemType::NODE) - { - if (firstSelectedNode.isValid()) - { - atLeastTwoNodes = true; - break; - } - else - { - firstSelectedNode = selected; - } - } - } + SetOptionEnabled(NAVIGATION_ZOOMSELECTION, anySelection); - if (m_parentPlugin->GetActionFilter().m_editNodes && - atLeastTwoNodes) - { - SetOptionEnabled(SELECTION_ALIGNLEFT, true); - SetOptionEnabled(SELECTION_ALIGNRIGHT, true); - SetOptionEnabled(SELECTION_ALIGNTOP, true); - SetOptionEnabled(SELECTION_ALIGNBOTTOM, true); - } - else + const auto isNodeSelected = [](const QModelIndex& index) { - SetOptionEnabled(SELECTION_ALIGNLEFT, false); - SetOptionEnabled(SELECTION_ALIGNRIGHT, false); - SetOptionEnabled(SELECTION_ALIGNTOP, false); - SetOptionEnabled(SELECTION_ALIGNBOTTOM, false); - } + return index.isValid() + && index.data(AnimGraphModel::ROLE_MODEL_ITEM_TYPE).value() == AnimGraphModel::ModelItemType::NODE; + }; + const QModelIndexList selectedIndexes = m_parentPlugin->GetAnimGraphModel().GetSelectionModel().selectedRows(); + const auto firstSelectedNode = AZStd::find_if(selectedIndexes.begin(), selectedIndexes.end(), isNodeSelected); + const auto secondSelectedNode = AZStd::find_if(firstSelectedNode, selectedIndexes.end(), isNodeSelected); + const bool atLeastTwoNodes = secondSelectedNode != selectedIndexes.end(); + + const bool enableAlignActions = m_parentPlugin->GetActionFilter().m_editNodes && atLeastTwoNodes; + SetOptionEnabled(SELECTION_ALIGNLEFT, enableAlignActions); + SetOptionEnabled(SELECTION_ALIGNRIGHT, enableAlignActions); + SetOptionEnabled(SELECTION_ALIGNTOP, enableAlignActions); + SetOptionEnabled(SELECTION_ALIGNBOTTOM, enableAlignActions); + + const bool isEditable = m_parentPlugin->GetGraphWidget()->GetActiveGraph() && !m_parentPlugin->GetGraphWidget()->GetActiveGraph()->IsInReferencedGraph(); + const AnimGraphActionFilter& actionFilter = m_parentPlugin->GetActionFilter(); + + SetOptionEnabled(EDIT_CUT, actionFilter.m_copyAndPaste && anySelection && isEditable); + SetOptionEnabled(EDIT_COPY, actionFilter.m_copyAndPaste && anySelection); + SetOptionEnabled(EDIT_PASTE, actionFilter.m_copyAndPaste && isEditable && m_parentPlugin->GetActionManager().GetIsReadyForPaste()); + SetOptionEnabled(EDIT_DELETE, actionFilter.m_copyAndPaste && anySelection && isEditable); } AnimGraphNodeWidget* BlendGraphViewWidget::GetWidgetForNode(const EMotionFX::AnimGraphNode* node) @@ -375,19 +564,17 @@ namespace EMStudio void BlendGraphViewWidget::SetOptionFlag(EOptionFlag option, bool isEnabled) { - const uint32 optionIndex = (uint32)option; - if (m_actions[optionIndex]) + if (m_actions[option]) { - m_actions[optionIndex]->setChecked(isEnabled); + m_actions[option]->setChecked(isEnabled); } } void BlendGraphViewWidget::SetOptionEnabled(EOptionFlag option, bool isEnabled) { - const uint32 optionIndex = (uint32)option; - if (m_actions[optionIndex]) + if (m_actions[option]) { - m_actions[optionIndex]->setEnabled(isEnabled); + m_actions[option]->setEnabled(isEnabled); } } @@ -395,8 +582,7 @@ namespace EMStudio { m_openMenu->clear(); - m_actions[FILE_OPEN] = m_openMenu->addAction(tr("Open...")); - connect(m_actions[FILE_OPEN], &QAction::triggered, m_parentPlugin, &AnimGraphPlugin::OnFileOpen); + m_openMenu->addAction(m_actions[FILE_OPEN]); const uint32 numAnimGraphs = EMotionFX::GetAnimGraphManager().GetNumAnimGraphs(); if (numAnimGraphs > 0) @@ -521,6 +707,19 @@ namespace EMStudio } } + void BlendGraphViewWidget::ZoomToAll() + { + BlendGraphWidget* blendGraphWidget = m_parentPlugin->GetGraphWidget(); + if (blendGraphWidget) + { + NodeGraph* nodeGraph = blendGraphWidget->GetActiveGraph(); + if (nodeGraph) + { + nodeGraph->FitGraphOnScreen(geometry().width(), geometry().height(), blendGraphWidget->GetMousePos()); + } + } + } + void BlendGraphViewWidget::OnActivateState() { // Transition to the selected state. @@ -546,7 +745,6 @@ namespace EMStudio } } - void BlendGraphViewWidget::NavigateToRoot() { const QModelIndex nodeModelIndex = m_parentPlugin->GetGraphWidget()->GetActiveGraph()->GetModelIndex(); @@ -556,20 +754,6 @@ namespace EMStudio } } - - void BlendGraphViewWidget::NavigateToParent() - { - const QModelIndex parentFocus = m_parentPlugin->GetAnimGraphModel().GetParentFocus(); - if (parentFocus.isValid()) - { - QModelIndex newParentFocus = parentFocus.model()->parent(parentFocus); - if (newParentFocus.isValid()) - { - m_parentPlugin->GetAnimGraphModel().Focus(newParentFocus); - } - } - } - void BlendGraphViewWidget::ToggleNavigationPane() { QList sizes = m_viewportSplitter->sizes(); @@ -588,16 +772,6 @@ namespace EMStudio m_viewportSplitter->setSizes(sizes); } - void BlendGraphViewWidget::NavigateToNode() - { - const QModelIndexList currentModelIndexes = m_parentPlugin->GetAnimGraphModel().GetSelectionModel().selectedRows(); - if (!currentModelIndexes.empty()) - { - const QModelIndex currentModelIndex = currentModelIndexes.front(); - m_parentPlugin->GetAnimGraphModel().Focus(currentModelIndex); - } - } - // toggle playspeed viz void BlendGraphViewWidget::OnDisplayPlaySpeeds() { @@ -638,36 +812,4 @@ namespace EMStudio EMotionFX::AnimGraphEditorNotificationBus::Broadcast(&EMotionFX::AnimGraphEditorNotificationBus::Events::OnShow); } - void BlendGraphViewWidget::keyPressEvent(QKeyEvent* event) - { - switch (event->key()) - { - case Qt::Key_Backspace: - { - m_parentPlugin->GetNavigationHistory()->StepBackward(); - event->accept(); - break; - } - - default: - event->ignore(); - } - } - - - // on key release - void BlendGraphViewWidget::keyReleaseEvent(QKeyEvent* event) - { - switch (event->key()) - { - case Qt::Key_Backspace: - { - event->accept(); - break; - } - - default: - event->ignore(); - } - } } // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.h index dbc200856a..196fadb115 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphViewWidget.h @@ -53,25 +53,32 @@ namespace EMStudio public: enum EOptionFlag { - SELECTION_ALIGNLEFT = 0, - SELECTION_ALIGNRIGHT = 1, - SELECTION_ALIGNTOP = 2, - SELECTION_ALIGNBOTTOM = 3, - FILE_NEW = 4, - FILE_OPENFILE = 5, - FILE_OPEN = 6, - FILE_SAVE = 7, - FILE_SAVEAS = 8, - NAVIGATION_FORWARD = 9, - NAVIGATION_BACK = 10, - NAVIGATION_NAVPANETOGGLE = 11, - SELECTION_ZOOMSELECTION = 12, - ACTIVATE_ANIMGRAPH = 13, - WINDOWS_NODEGROUPWINDOW = 14, - VISUALIZATION_PLAYSPEEDS = 15, - VISUALIZATION_GLOBALWEIGHTS = 16, - VISUALIZATION_SYNCSTATUS = 17, - VISUALIZATION_PLAYPOSITIONS = 18, + SELECTION_ALIGNLEFT, + SELECTION_ALIGNRIGHT, + SELECTION_ALIGNTOP, + SELECTION_ALIGNBOTTOM, + SELECTION_SELECTALL, + SELECTION_UNSELECTALL, + FILE_NEW, + FILE_OPEN, + FILE_SAVE, + FILE_SAVEAS, + NAVIGATION_FORWARD, + NAVIGATION_BACK, + NAVIGATION_NAVPANETOGGLE, + NAVIGATION_OPEN_SELECTED, + NAVIGATION_TO_PARENT, + NAVIGATION_FRAME_ALL, + NAVIGATION_ZOOMSELECTION, + ACTIVATE_ANIMGRAPH, + VISUALIZATION_PLAYSPEEDS, + VISUALIZATION_GLOBALWEIGHTS, + VISUALIZATION_SYNCSTATUS, + VISUALIZATION_PLAYPOSITIONS, + EDIT_CUT, + EDIT_COPY, + EDIT_PASTE, + EDIT_DELETE, NUM_OPTIONS //automatically gets the next number assigned }; @@ -85,13 +92,12 @@ namespace EMStudio void Init(BlendGraphWidget* blendGraphWidget); void UpdateAnimGraphOptions(); - void UpdateSelection(); + void UpdateEnabledActions(); // If there is a specific widget to handle this node returns that. // Else, returns nullptr. AnimGraphNodeWidget* GetWidgetForNode(const EMotionFX::AnimGraphNode* node); - // Get Actions (used for testing purposes) QAction* GetAction(EOptionFlag option) const { return m_actions[option]; } public slots: @@ -100,11 +106,10 @@ namespace EMStudio void OnCreateAnimGraph(); void NavigateToRoot(); - void NavigateToNode(); - void NavigateToParent(); void ToggleNavigationPane(); void ZoomSelected(); + void ZoomToAll(); void OnActivateState(); @@ -122,17 +127,15 @@ namespace EMStudio void showEvent(QShowEvent* showEvent); - void keyReleaseEvent(QKeyEvent* event) override; - void keyPressEvent(QKeyEvent* event) override; - private: + void CreateActions(); QToolBar* CreateTopToolBar(); QToolBar* CreateNavigationToolBar(); QMenuBar* m_menu = nullptr; QMenu* m_openMenu = nullptr; QHBoxLayout* m_toolbarLayout = nullptr; - QAction* m_actions[NUM_OPTIONS]; + AZStd::array m_actions{}; AnimGraphPlugin* m_parentPlugin = nullptr; NavigationLinkWidget* mNavigationLink = nullptr; QStackedWidget m_viewportStack; diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp index 7cd5a2d849..623f9f94a9 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.cpp @@ -71,12 +71,6 @@ namespace EMStudio } - // destructor - BlendGraphWidget::~BlendGraphWidget() - { - } - - // when dropping stuff in our window void BlendGraphWidget::dropEvent(QDropEvent* event) { @@ -1555,254 +1549,6 @@ namespace EMStudio } - // on keypress - void BlendGraphWidget::keyPressEvent(QKeyEvent* event) - { - MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - const AnimGraphActionFilter& actionFilter = mPlugin->GetActionFilter(); - - if (shortcutManager->Check(event, "Open Parent Node", "Anim Graph Window")) - { - const QModelIndex parentFocus = mPlugin->GetAnimGraphModel().GetParentFocus(); - if (parentFocus.isValid()) - { - QModelIndex newParentFocus = parentFocus.model()->parent(parentFocus); - if (newParentFocus.isValid()) - { - mPlugin->GetAnimGraphModel().Focus(newParentFocus); - } - } - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Open Selected Node", "Anim Graph Window")) - { - mPlugin->GetActionManager().NavigateToNode(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "History Back", "Anim Graph Window")) - { - mPlugin->GetNavigationHistory()->StepBackward(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "History Forward", "Anim Graph Window")) - { - mPlugin->GetNavigationHistory()->StepForward(); - event->accept(); - return; - } - - if (mActiveGraph && - !mActiveGraph->IsInReferencedGraph()) - { - if (actionFilter.m_editNodes) - { - if (shortcutManager->Check(event, "Align Left", "Anim Graph Window")) - { - mPlugin->GetActionManager().AlignLeft(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Align Right", "Anim Graph Window")) - { - mPlugin->GetActionManager().AlignRight(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Align Top", "Anim Graph Window")) - { - mPlugin->GetActionManager().AlignTop(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Align Bottom", "Anim Graph Window")) - { - mPlugin->GetActionManager().AlignBottom(); - event->accept(); - return; - } - } - - if (actionFilter.m_copyAndPaste && - shortcutManager->Check(event, "Cut", "Anim Graph Window")) - { - mPlugin->GetActionManager().Cut(); - event->accept(); - return; - } - } - - if (actionFilter.m_copyAndPaste) - { - if (shortcutManager->Check(event, "Copy", "Anim Graph Window")) - { - mPlugin->GetActionManager().Copy(); - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Paste", "Anim Graph Window")) - { - if (mActiveGraph && !mActiveGraph->IsInReferencedGraph()) - { - if (mPlugin->GetActionManager().GetIsReadyForPaste()) - { - QModelIndex modelIndex = GetActiveGraph()->GetModelIndex(); - if (modelIndex.isValid()) - { - if (rect().contains(mapFromGlobal(QCursor::pos())) == false) - { - mPlugin->GetActionManager().Paste(modelIndex, GetMousePos()); - event->accept(); - } - } - } - } - return; - } - } - - if (shortcutManager->Check(event, "Select All", "Anim Graph Window")) - { - if (mActiveGraph) - { - mActiveGraph->SelectAllNodes(); - event->accept(); - } - return; - } - - if (shortcutManager->Check(event, "Unselect All", "Anim Graph Window")) - { - if (mActiveGraph) - { - mActiveGraph->UnselectAllNodes(); - event->accept(); - } - return; - } - - if (mActiveGraph && - actionFilter.m_delete && - !mActiveGraph->IsInReferencedGraph() && - shortcutManager->Check(event, "Delete Selected Nodes", "Anim Graph Window")) - { - DeleteSelectedItems(); - event->accept(); - return; - } - - return NodeGraphWidget::keyPressEvent(event); - } - - - // on key release - void BlendGraphWidget::keyReleaseEvent(QKeyEvent* event) - { - MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - const AnimGraphActionFilter& actionFilter = mPlugin->GetActionFilter(); - - if (shortcutManager->Check(event, "Open Parent Node", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "Open Selected Node", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "History Back", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "History Forward", "Anim Graph Window")) - { - event->accept(); - return; - } - - if (mActiveGraph && !mActiveGraph->IsInReferencedGraph()) - { - if (actionFilter.m_editNodes) - { - if (shortcutManager->Check(event, "Align Left", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "Align Right", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "Align Top", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "Align Bottom", "Anim Graph Window")) - { - event->accept(); - return; - } - } - - if (actionFilter.m_copyAndPaste && - shortcutManager->Check(event, "Cut", "Anim Graph Window")) - { - event->accept(); - return; - } - } - - if (actionFilter.m_copyAndPaste) - { - if (shortcutManager->Check(event, "Copy", "Anim Graph Window")) - { - event->accept(); - return; - } - if (mActiveGraph && !mActiveGraph->IsInReferencedGraph() && shortcutManager->Check(event, "Paste", "Anim Graph Window")) - { - event->accept(); - return; - } - } - - if (shortcutManager->Check(event, "Select All", "Anim Graph Window")) - { - event->accept(); - return; - } - if (shortcutManager->Check(event, "Unselect All", "Anim Graph Window")) - { - event->accept(); - return; - } - - if (mActiveGraph && - actionFilter.m_delete && - !mActiveGraph->IsInReferencedGraph() && - shortcutManager->Check(event, "Delete Selected Nodes", "Anim Graph Window")) - { - event->accept(); - return; - } - - return NodeGraphWidget::keyReleaseEvent(event); - } - - void BlendGraphWidget::OnRowsInserted(const QModelIndex& parent, int first, int last) { // Here we could be receiving connections, transitions or nodes being inserted into diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.h index f5c5d4a5ea..7453e4cc53 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/BlendGraphWidget.h @@ -45,7 +45,6 @@ namespace EMStudio public: BlendGraphWidget(AnimGraphPlugin* plugin, QWidget* parent); - ~BlendGraphWidget(); // overloaded bool CheckIfIsCreateConnectionValid(uint32 portNr, GraphNode* portNode, NodePort* port, bool isInputPort) override; @@ -120,8 +119,6 @@ namespace EMStudio void OnSelectionModelChanged(const QItemSelection& selected, const QItemSelection& deselected); private: - void keyReleaseEvent(QKeyEvent* event) override; - void keyPressEvent(QKeyEvent* event) override; EMotionFX::AnimGraphStateTransition* FindTransitionForConnection(NodeConnection* connection) const; EMotionFX::BlendTreeConnection* FindBlendTreeConnection(NodeConnection* connection) const; diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/ContextMenu.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/ContextMenu.cpp index 8866ec678e..80603c37bf 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/ContextMenu.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/ContextMenu.cpp @@ -183,17 +183,11 @@ namespace EMStudio if (graphNode == nullptr) { QMenu* menu = new QMenu(parentWidget); - if (actionFilter.m_copyAndPaste && actionManager.GetIsReadyForPaste()) - { - const QModelIndex modelIndex = nodeGraph->GetModelIndex(); - if (modelIndex.isValid()) - { - localMousePos = SnapLocalToGrid(LocalToGlobal(localMousePos)); - QAction* pasteAction = menu->addAction("Paste"); - connect(pasteAction, &QAction::triggered, [&actionManager, modelIndex, localMousePos]() { actionManager.Paste(modelIndex, localMousePos); }); - menu->addSeparator(); - } + if (actionFilter.m_copyAndPaste && actionManager.GetIsReadyForPaste() && nodeGraph->GetModelIndex().isValid()) + { + menu->addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_PASTE)); + menu->addSeparator(); } if (actionFilter.m_createNodes) @@ -324,8 +318,7 @@ namespace EMStudio // we can only go to the selected node in case the selected node has a visual graph (state machine / blend tree) if (animGraphNode->GetHasVisualGraph()) { - QAction* goToNodeAction = menu->addAction("Open Selected Node"); - connect(goToNodeAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::NavigateToNode); + menu->addAction(viewWidget->GetAction(BlendGraphViewWidget::NAVIGATION_OPEN_SELECTED)); menu->addSeparator(); } @@ -360,20 +353,17 @@ namespace EMStudio if (!inReferenceGraph) { // cut and copy actions - QAction* cutAction = menu->addAction("Cut"); - connect(cutAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::Cut); + menu->addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_CUT)); } - QAction* ccopyAction = menu->addAction("Copy"); - connect(ccopyAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::Copy); + menu->addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_COPY)); menu->addSeparator(); } if (actionFilter.m_delete && !inReferenceGraph) { - QAction* removeNodeAction = menu->addAction("Delete Node"); - connect(removeNodeAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::DeleteSelectedNodes); + menu->addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_DELETE)); menu->addSeparator(); } } @@ -403,22 +393,14 @@ namespace EMStudio if (actionFilter.m_editNodes && !inReferenceGraph) { - QAction* alignLeftAction = menu.addAction("Align Left"); - QAction* alignRightAction = menu.addAction("Align Right"); - QAction* alignTopAction = menu.addAction("Align Top"); - QAction* alignBottomAction = menu.addAction("Align Bottom"); - - - connect(alignLeftAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::AlignLeft); - connect(alignRightAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::AlignRight); - connect(alignTopAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::AlignTop); - connect(alignBottomAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::AlignBottom); - + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::SELECTION_ALIGNLEFT)); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::SELECTION_ALIGNRIGHT)); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::SELECTION_ALIGNTOP)); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::SELECTION_ALIGNBOTTOM)); menu.addSeparator(); } - QAction* zoomSelectionAction = menu.addAction("Zoom Selection"); - connect(zoomSelectionAction, &QAction::triggered, viewWidget, &BlendGraphViewWidget::ZoomSelected); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::NAVIGATION_ZOOMSELECTION)); menu.addSeparator(); @@ -494,12 +476,10 @@ namespace EMStudio if (!inReferenceGraph) { - QAction* cutAction = menu.addAction("Cut"); - connect(cutAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::Cut); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_CUT)); } - QAction* ccopyAction = menu.addAction("Copy"); - connect(ccopyAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::Copy); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_COPY)); } menu.addSeparator(); @@ -507,8 +487,7 @@ namespace EMStudio if (actionFilter.m_delete && !inReferenceGraph) { - QAction* removeNodesAction = menu.addAction("Delete Nodes"); - connect(removeNodesAction, &QAction::triggered, &actionManager, &AnimGraphActionManager::DeleteSelectedNodes); + menu.addAction(viewWidget->GetAction(BlendGraphViewWidget::EDIT_DELETE)); menu.addSeparator(); } @@ -526,4 +505,4 @@ namespace EMStudio } } } -} +} // namespace EMStudio diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.cpp index eae890c69d..f102cc5d96 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -155,6 +154,11 @@ namespace EMStudio // set the active graph void NodeGraphWidget::SetActiveGraph(NodeGraph* graph) { + if (mActiveGraph == graph) + { + return; + } + if (mActiveGraph) { mActiveGraph->StopCreateConnection(); @@ -165,6 +169,8 @@ namespace EMStudio mActiveGraph = graph; mMoveNode = nullptr; + + emit ActiveGraphChanged(); } @@ -322,7 +328,7 @@ namespace EMStudio // convert to a global position - QPoint NodeGraphWidget::LocalToGlobal(const QPoint& inPoint) + QPoint NodeGraphWidget::LocalToGlobal(const QPoint& inPoint) const { if (mActiveGraph) { @@ -334,7 +340,7 @@ namespace EMStudio // convert to a local position - QPoint NodeGraphWidget::GlobalToLocal(const QPoint& inPoint) + QPoint NodeGraphWidget::GlobalToLocal(const QPoint& inPoint) const { if (mActiveGraph) { @@ -345,7 +351,7 @@ namespace EMStudio } - QPoint NodeGraphWidget::SnapLocalToGrid(const QPoint& inPoint, uint32 cellSize) + QPoint NodeGraphWidget::SnapLocalToGrid(const QPoint& inPoint, uint32 cellSize) const { MCORE_UNUSED(cellSize); @@ -1491,45 +1497,9 @@ namespace EMStudio } } - MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - - if (shortcutManager->Check(event, "Fit Entire Graph", "Anim Graph Window")) - { - // zoom to fit the entire graph in view - if (mActiveGraph) - { - mActiveGraph->FitGraphOnScreen(geometry().width(), geometry().height(), GetMousePos()); - } - - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Zoom On Selected Nodes", "Anim Graph Window")) - { - if (mActiveGraph) - { - // try zooming on the selection rect - QRect selectionRect = mActiveGraph->CalcRectFromSelection(true); - if (selectionRect.isEmpty() == false) - { - mActiveGraph->ZoomOnRect(selectionRect, geometry().width(), geometry().height()); - //update(); - } - else // zoom on the full scene - { - mActiveGraph->FitGraphOnScreen(geometry().width(), geometry().height(), GetMousePos()); - } - } - - event->accept(); - return; - } - event->ignore(); } - // on key release void NodeGraphWidget::keyReleaseEvent(QKeyEvent* event) { @@ -1552,20 +1522,6 @@ namespace EMStudio } } - MysticQt::KeyboardShortcutManager* shortcutManager = GetMainWindow()->GetShortcutManager(); - - if (shortcutManager->Check(event, "Fit Entire Graph", "Anim Graph Window")) - { - event->accept(); - return; - } - - if (shortcutManager->Check(event, "Zoom On Selected Nodes", "Anim Graph Window")) - { - event->accept(); - return; - } - event->ignore(); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.h b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.h index 68e9f72209..9b8d8c6ace 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.h +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/NodeGraphWidget.h @@ -65,9 +65,9 @@ namespace EMStudio uint32 CalcNumSelectedNodes() const; - QPoint LocalToGlobal(const QPoint& inPoint); - QPoint GlobalToLocal(const QPoint& inPoint); - QPoint SnapLocalToGrid(const QPoint& inPoint, uint32 cellSize = 10); + QPoint LocalToGlobal(const QPoint& inPoint) const; + QPoint GlobalToLocal(const QPoint& inPoint) const; + QPoint SnapLocalToGrid(const QPoint& inPoint, uint32 cellSize = 10) const; void CalcSelectRect(QRect& outRect); @@ -106,6 +106,9 @@ namespace EMStudio const QString& GetTitleBarText() const { return m_titleBarText; } void SetTitleBarText(const QString& text) { m_titleBarText = text; } + signals: + void ActiveGraphChanged(); + protected: //virtual void paintEvent(QPaintEvent* event); void mouseMoveEvent(QMouseEvent* event) override; @@ -160,4 +163,4 @@ namespace EMStudio float m_borderOverwriteWidth; QString m_titleBarText; }; -} // namespace EMStudio +} // namespace EMStudio diff --git a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp index 202feb3d18..0d44330b34 100644 --- a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp +++ b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.cpp @@ -12,6 +12,8 @@ // include required headers #include "KeyboardShortcutManager.h" +#include +#include #include #include @@ -19,52 +21,27 @@ #include #include - namespace MysticQt { - // find action by name - KeyboardShortcutManager::Action* KeyboardShortcutManager::Group::FindActionByName(const char* actionName, bool local) const + void KeyboardShortcutManager::Group::RemoveAction(QAction* qaction, bool local) { - const uint32 numActions = mActions.GetLength(); - for (uint32 i = 0; i < numActions; ++i) + m_actions.erase(AZStd::find_if(begin(m_actions), end(m_actions), [&qaction, local](const AZStd::unique_ptr& action) { - if (mActions[i]->mLocal == local && mActions[i]->mName == actionName) - { - return mActions[i]; - } - } - - return nullptr; + return action->m_local == local && action->m_qaction == qaction; + })); } - // constructor - KeyboardShortcutManager::KeyboardShortcutManager() + KeyboardShortcutManager::Action* KeyboardShortcutManager::Group::FindActionByName(const QString& actionName, bool local) const { - } - - - // destructor - KeyboardShortcutManager::~KeyboardShortcutManager() - { - Clear(); - } - - - // get rid of all groups including their actions - void KeyboardShortcutManager::Clear() - { - // get rid of the groups - const uint32 numGroups = mGroups.GetLength(); - for (uint32 i = 0; i < numGroups; ++i) + const auto found = AZStd::find_if(begin(m_actions), end(m_actions), [&actionName, local](const AZStd::unique_ptr& action) { - delete mGroups[i]; - } + return action->m_local == local && action->m_qaction->text() == actionName; + }); - mGroups.Clear(); + return found != end(m_actions) ? found->get() : nullptr; } - - void KeyboardShortcutManager::RegisterKeyboardShortcut(const char* actionName, const char* groupName, int defaultKey, bool defaultCtrl, bool defaultAlt, bool local) + void KeyboardShortcutManager::RegisterKeyboardShortcut(QAction* qaction, AZStd::string_view groupName, bool local) { // find the group with the given name Group* group = FindGroupByName(groupName); @@ -72,188 +49,112 @@ namespace MysticQt // if there is no group with the given name, create it if (group == nullptr) { - group = new Group(groupName); - mGroups.Add(group); + m_groups.emplace_back(AZStd::make_unique(groupName)); + group = m_groups.back().get(); } // check if the action is already there to avoid adding it twice - Action* action = group->FindActionByName(actionName, local); + Action* action = group->FindActionByName(qaction->text(), local); if (action) { - action->mDefaultKey = defaultKey; - action->mDefaultCtrl = defaultCtrl; - action->mDefaultAlt = defaultAlt; + action->m_defaultKeySequence = qaction->shortcut(); return; } // create the new action and add it to the group - action = new Action(actionName, defaultKey, defaultCtrl, defaultAlt, local); - group->AddAction(action); - } - + group->AddAction(AZStd::make_unique(qaction, local)); - // find the action with the given name in the given group - KeyboardShortcutManager::Action* KeyboardShortcutManager::FindAction(const char* actionName, const char* groupName) - { - const uint32 numGroups = mGroups.GetLength(); - - // first search global shortcuts - for (uint32 i = 0; i < numGroups; ++i) + QAction::connect(qaction, &QAction::destroyed, this, [this, groupName = AZStd::string(groupName), local](QObject* qaction) { - if (mGroups[i]->GetNameString() == groupName) - { - Action* action = mGroups[i]->FindActionByName(actionName, false); - if (action) - { - return action; - } - } - } - - // then local shortcuts - for (uint32 i = 0; i < numGroups; ++i) - { - if (mGroups[i]->GetNameString() == groupName) - { - Action* action = mGroups[i]->FindActionByName(actionName, true); - if (action) - { - return action; - } - } - } - - // failure, not found - return nullptr; + UnregisterKeyboardShortcut(static_cast(qaction), groupName, local); + }); } - - // find a group by name - KeyboardShortcutManager::Group* KeyboardShortcutManager::FindGroupByName(const char* groupName) const + void KeyboardShortcutManager::UnregisterKeyboardShortcut(QAction* qaction, AZStd::string_view groupName, bool local) { - // iterate through the groups and find the one with the given name - const uint32 numGroups = mGroups.GetLength(); - for (uint32 i = 0; i < numGroups; ++i) + Group* group = FindGroupByName(groupName); + + if (!group) { - if (mGroups[i]->GetNameString() == groupName) - { - return mGroups[i]; - } + return; } - // failure, a group with the given name hasn't been found - return nullptr; + group->RemoveAction(qaction, local); } - bool KeyboardShortcutManager::Check(QKeyEvent* event, const char* actionName, const char* groupName) + // find the action with the given name in the given group + KeyboardShortcutManager::Action* KeyboardShortcutManager::FindAction(const QString& actionName, AZStd::string_view groupName) const { - // find the corresponding action for the given strings - Action* action = FindAction(actionName, groupName); - if (action == nullptr) + const Group* group = FindGroupByName(groupName); + if (!group) { - //MCore::LogError("Action named '%s' in group '%s' not registered. Please register the shortcut before using it.", actionName, groupName); - return false; + return nullptr; } - const bool ctrlPressed = event->modifiers() & Qt::ControlModifier; - //const bool shiftPressed = event->modifiers() & Qt::ShiftModifier; - const bool altPressed = event->modifiers() & Qt::AltModifier; - - Group* group = FindGroupByName(groupName); - Action* conflictAction = FindShortcut(event->key(), ctrlPressed, altPressed, group); - - // check if they are equal, if yes this means they match - if (action == conflictAction) + Action* action = group->FindActionByName(actionName, false); + if (action) { - return true; + return action; } + return group->FindActionByName(actionName, true); + } - // check if the action and the key event are the same shortcut - /*if (event->key() == action->mKey && - ctrlPressed == action->mCtrl && - altPressed == action->mAlt) - return true;*/ - return false; + // find a group by name + KeyboardShortcutManager::Group* KeyboardShortcutManager::FindGroupByName(AZStd::string_view groupName) const + { + const auto found = AZStd::find_if(begin(m_groups), end(m_groups), [&groupName](const AZStd::unique_ptr& group) + { + return group->GetName() == groupName; + }); + return found != end(m_groups) ? found->get() : nullptr; } // find the correspondng group for the given action - KeyboardShortcutManager::Group* KeyboardShortcutManager::FindGroupForShortcut(Action* action) + KeyboardShortcutManager::Group* KeyboardShortcutManager::FindGroupForShortcut(Action* action) const { - // get the number of available groups - const uint32 numGroups = mGroups.GetLength(); - - // first check the global shortcuts - for (uint32 i = 0; i < numGroups; ++i) + const auto foundGroup = AZStd::find_if(begin(m_groups), end(m_groups), [action](const AZStd::unique_ptr& group) { - Group* group = mGroups[i]; - - // iterate through the actions and save them - const uint32 numActions = group->GetNumActions(); - for (uint32 j = 0; j < numActions; ++j) + const auto foundAction = AZStd::find_if(begin(group->GetActions()), end(group->GetActions()), [action](const AZStd::unique_ptr& actionInGroup) { - if (group->GetAction(j) == action) - { - return group; - } - } - } - - // failure, not found - return nullptr; + return action == actionInGroup.get(); + }); + return foundAction != end(group->GetActions()) ? foundAction->get() : nullptr; + }); + return foundGroup != end(m_groups) ? foundGroup->get() : nullptr; } - KeyboardShortcutManager::Action* KeyboardShortcutManager::FindShortcut(int key, bool ctrl, bool alt, Group* group) + KeyboardShortcutManager::Action* KeyboardShortcutManager::FindShortcut(QKeySequence keySequence, Group* group) const { - // get the number of available groups - const uint32 numGroups = mGroups.GetLength(); - - // first check the global shortcuts - for (uint32 i = 0; i < numGroups; ++i) + const auto findMatchingAction = [keySequence] (const Group* group, const bool local) { - Group* currentGroup = mGroups[i]; - - // iterate through the actions and save them - const uint32 numActions = currentGroup->GetNumActions(); - for (uint32 j = 0; j < numActions; ++j) + return AZStd::find_if(begin(group->GetActions()), end(group->GetActions()), [keySequence, local] (const AZStd::unique_ptr& action) { - // get the shortcut action - KeyboardShortcutManager::Action* action = currentGroup->GetAction(j); - if (action->mLocal) + if (action->m_local != local) { - continue; + return false; } - // check if the action and shortcut are the same - if (key == action->mKey && - ctrl == action->mCtrl && - alt == action->mAlt) - { - return action; - } - } - } + return action->m_qaction->shortcut().matches(keySequence) == QKeySequence::ExactMatch; + }); + }; - // iterate through the actions and save them - const uint32 numActions = group->GetNumActions(); - for (uint32 j = 0; j < numActions; ++j) + // first check the global shortcuts + const auto globalAction = findMatchingAction(group, false); + if (globalAction != end(group->GetActions())) { - // get the shortcut action - KeyboardShortcutManager::Action* action = group->GetAction(j); + return globalAction->get(); + } - // check if the action and shortcut are the same - if (key == action->mKey && - ctrl == action->mCtrl && - alt == action->mAlt) - { - return action; - } + const auto localAction = findMatchingAction(group, true); + if (localAction != end(group->GetActions())) + { + return localAction->get(); } - // failure, shortcut not found return nullptr; } @@ -264,24 +165,16 @@ namespace MysticQt settings->clear(); // iterate through the groups and save all actions for them - const uint32 numGroups = mGroups.GetLength(); - for (uint32 i = 0; i < numGroups; ++i) + for (const AZStd::unique_ptr& group : m_groups) { - Group* group = mGroups[i]; - settings->beginGroup(group->GetName()); + settings->beginGroup(QString::fromUtf8(group->GetName().data(), group->GetName().size())); // iterate through the actions and save them - const uint32 numActions = group->GetNumActions(); - for (uint32 j = 0; j < numActions; ++j) + for (const AZStd::unique_ptr& action : group->GetActions()) { - // get the shortcut action - KeyboardShortcutManager::Action* action = group->GetAction(j); - - settings->beginGroup(action->mName.c_str()); - settings->setValue("Key", action->mKey); - settings->setValue("Ctrl", action->mCtrl); - settings->setValue("Alt", action->mAlt); - settings->setValue("Local", action->mLocal); + settings->beginGroup(action->m_qaction->text()); + settings->setValue("Key", action->m_qaction->shortcut()); + settings->setValue("Local", action->m_local); settings->endGroup(); } @@ -292,33 +185,49 @@ namespace MysticQt void KeyboardShortcutManager::Load(QSettings* settings) { - // clear the shortcut manager before loading - Clear(); - // iterate through the groups and load all actions - QStringList groupNames = settings->childGroups(); - const uint32 numGroups = groupNames.count(); - for (uint32 i = 0; i < numGroups; ++i) + const QStringList groupNames = settings->childGroups(); + for (const QString& groupName : groupNames) { - QString groupName = groupNames[i]; - settings->beginGroup(groupNames[i]); - QStringList actionNames = settings->childGroups(); + Group* group = FindGroupByName(FromQtString(groupName)); + if (!group) + { + continue; + } + + settings->beginGroup(groupName); + const QStringList actionNames = settings->childGroups(); // iterate through the actions and save them - const uint32 numActions = actionNames.count(); - for (uint32 j = 0; j < numActions; ++j) + for (const QString& actionName : actionNames) { - QString actionName = actionNames[j]; settings->beginGroup(actionName); - int key = settings->value("Key", "").toInt(); - bool ctrlPressed = settings->value("Ctrl", false).toBool(); - bool altPressed = settings->value("Alt", false).toBool(); - bool local = settings->value("Local", false).toBool(); - RegisterKeyboardShortcut(FromQtString(actionName).c_str(), FromQtString(groupName).c_str(), key, ctrlPressed, altPressed, local); + const bool local = settings->value("Local", false).toBool(); + + Action* action = group->FindActionByName(actionName, local); + if (!action) + { + continue; + } + + const QVariant keyValue = settings->value("Key", ""); + if (keyValue.canConvert()) + { + const QKeySequence key = keyValue.value(); + action->m_qaction->setShortcut(key); + } + else if (keyValue.canConvert()) + { + const int key = keyValue.value(); + const bool ctrlModifier = settings->value("Ctrl", false).value(); + const bool altModifier = settings->value("Alt", false).value(); + action->m_qaction->setShortcut(key | (ctrlModifier ? Qt::ControlModifier : 0) | (altModifier ? Qt::AltModifier : 0)); + } + settings->endGroup(); } settings->endGroup(); } } -} // namespace MysticQt +} // namespace MysticQt diff --git a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.h b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.h index 9bd1b58812..ce989767e0 100644 --- a/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.h +++ b/Gems/EMotionFX/Code/MysticQt/Source/KeyboardShortcutManager.h @@ -10,12 +10,14 @@ * */ -#ifndef __MYSTICQT_KEYBOARDSHORTCUTMANAGER_H -#define __MYSTICQT_KEYBOARDSHORTCUTMANAGER_H +#pragma once #if !defined(Q_MOC_RUN) +#include +#include +#include #include -#include +#include #include #include "MysticQtConfig.h" #endif @@ -26,86 +28,58 @@ class QSettings; namespace MysticQt { class MYSTICQT_API KeyboardShortcutManager + : public QObject { - MCORE_MEMORYOBJECTCATEGORY(KeyboardShortcutManager, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_MYSTICQT); - public: - KeyboardShortcutManager(); - virtual ~KeyboardShortcutManager(); - struct Action { - MCORE_MEMORYOBJECTCATEGORY(KeyboardShortcutManager::Action, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_MYSTICQT); - - AZStd::string mName; - int mKey; - bool mCtrl; - bool mAlt; - bool mLocal; - - int mDefaultKey; - bool mDefaultCtrl; - bool mDefaultAlt; - - Action(const char* name, int defaultKey, bool defaultCtrl, bool defaultAlt, bool local) + QAction* m_qaction; + QKeySequence m_defaultKeySequence; + bool m_local; + + Action(QAction* qaction, bool local) + : m_qaction(qaction) + , m_defaultKeySequence(qaction->shortcut()) + , m_local(local) { - mName = name; - mLocal = local; - - mKey = defaultKey; - mCtrl = defaultCtrl; - mAlt = defaultAlt; - - mDefaultKey = defaultKey; - mDefaultCtrl = defaultCtrl; - mDefaultAlt = defaultAlt; } }; class Group { - MCORE_MEMORYOBJECTCATEGORY(KeyboardShortcutManager::Group, MCore::MCORE_DEFAULT_ALIGNMENT, MEMCATEGORY_MYSTICQT); public: - Group(const char* groupName) { mName = groupName; } - virtual ~Group() + Group(AZStd::string_view groupName) + : m_name(groupName) { - const uint32 numActions = mActions.GetLength(); - for (uint32 i = 0; i < numActions; ++i) - { - delete mActions[i]; - } - mActions.Clear(); } - void AddAction(Action* action) { mActions.Add(action); } - uint32 GetNumActions() const { return mActions.GetLength(); } - Action* GetAction(uint32 index) { return mActions[index]; } - const char* GetName() const { return mName.c_str(); } - const AZStd::string& GetNameString() const { return mName; } - Action* FindActionByName(const char* actionName, bool local) const; + + void AddAction(AZStd::unique_ptr action) { m_actions.emplace_back(AZStd::move(action)); } + void RemoveAction(QAction* action, bool local); + size_t GetNumActions() const { return m_actions.size(); } + Action* GetAction(size_t index) { return m_actions[index].get(); } + const AZStd::vector>& GetActions() const { return m_actions; } + const AZStd::string& GetName() const { return m_name; } + Action* FindActionByName(const QString& actionName, bool local) const; private: - AZStd::string mName; - MCore::Array mActions; + AZStd::string m_name; + AZStd::vector> m_actions; }; - void RegisterKeyboardShortcut(const char* actionName, const char* groupName, int defaultKey, bool defaultCtrl, bool defaultAlt, bool local); - bool Check(QKeyEvent* event, const char* actionName, const char* groupName); - Action* FindShortcut(int key, bool ctrl, bool alt, Group* group); - Action* FindAction(const char* actionName, const char* groupName); - Group* FindGroupForShortcut(Action* action); - uint32 GetNumGroups() const { return mGroups.GetLength(); } - Group* GetGroup(uint32 index) const { return mGroups[index]; } - void Clear(); + void RegisterKeyboardShortcut(QAction* qaction, AZStd::string_view groupName, bool local); + void UnregisterKeyboardShortcut(QAction* qaction, AZStd::string_view groupName, bool local); + Action* FindShortcut(QKeySequence keySequence, Group* group) const; + Action* FindAction(const QString& actionName, AZStd::string_view groupName) const; + Group* FindGroupForShortcut(Action* action) const; + size_t GetNumGroups() const { return m_groups.size(); } + Group* GetGroup(size_t index) const { return m_groups[index].get(); } void Save(QSettings* settings); void Load(QSettings* settings); private: - MCore::Array mGroups; + AZStd::vector> m_groups; - Group* FindGroupByName(const char* groupName) const; + Group* FindGroupByName(AZStd::string_view groupName) const; }; } // namespace MysticQt - - -#endif diff --git a/Gems/EMotionFX/Code/MysticQt/Source/MysticQtConfig.h b/Gems/EMotionFX/Code/MysticQt/Source/MysticQtConfig.h index 54d2fddb54..90df0bf418 100644 --- a/Gems/EMotionFX/Code/MysticQt/Source/MysticQtConfig.h +++ b/Gems/EMotionFX/Code/MysticQt/Source/MysticQtConfig.h @@ -39,14 +39,19 @@ enum // convert from a QString into an AZStd::string MCORE_INLINE AZStd::string FromQtString(const QString& s) { - return s.toUtf8().data(); + return {s.toUtf8().data(), static_cast(s.size())}; } // convert from a QString into an AZStd::string MCORE_INLINE void FromQtString(const QString& s, AZStd::string* result) { - *result = s.toUtf8().data(); + *result = AZStd::string{s.toUtf8().data(), static_cast(s.size())}; +} + +inline QString FromStdString(AZStd::string_view s) +{ + return QString::fromUtf8(s.data(), static_cast(s.size())); } // forward declare a MysticQt class diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp index e3de713b3c..8ef87af9a7 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/ActorComponent.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include @@ -414,9 +413,6 @@ namespace EMotionFX CheckAttachToEntity(); - // Send general mesh creation notification to interested parties. - LmbrCentral::MeshComponentNotificationBus::Event(entityId, &LmbrCentral::MeshComponentNotifications::OnMeshCreated, m_configuration.m_actorAsset); - Physics::RagdollConfiguration ragdollConfiguration; [[maybe_unused]] bool ragdollConfigValid = GetRagdollConfiguration(ragdollConfiguration); AZ_Assert(ragdollConfigValid, "Ragdoll Configuration is not valid"); @@ -460,11 +456,6 @@ namespace EMotionFX m_attachmentTargetActor = nullptr; - // Send general mesh destruction notification to interested parties. - LmbrCentral::MeshComponentNotificationBus::Event( - GetEntityId(), - &LmbrCentral::MeshComponentNotifications::OnMeshDestroyed); - ActorComponentNotificationBus::Event( GetEntityId(), &ActorComponentNotificationBus::Events::OnActorInstanceDestroyed, diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp index 6958710b1a..eee9896dee 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Components/AnimAudioComponent.cpp @@ -22,7 +22,7 @@ #include #include -#include // for SkeletalHierarchyRequestBus +#include #include diff --git a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp index bcb1e3f300..f45fe43f4e 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Editor/Components/EditorActorComponent.cpp @@ -26,8 +26,6 @@ #include #include -#include - #include #include #include @@ -255,11 +253,6 @@ namespace EMotionFX { if (m_actorInstance) { - // Send general mesh destruction notification to interested parties. - LmbrCentral::MeshComponentNotificationBus::Event( - GetEntityId(), - &LmbrCentral::MeshComponentNotifications::OnMeshDestroyed); - ActorComponentNotificationBus::Event( GetEntityId(), &ActorComponentNotificationBus::Events::OnActorInstanceDestroyed, @@ -848,11 +841,6 @@ namespace EMotionFX if (m_actorInstance) { - // Send general mesh destruction notification to interested parties. - LmbrCentral::MeshComponentNotificationBus::Event( - GetEntityId(), - &LmbrCentral::MeshComponentNotifications::OnMeshDestroyed); - ActorComponentNotificationBus::Event( GetEntityId(), &ActorComponentNotificationBus::Events::OnActorInstanceDestroyed, @@ -941,9 +929,6 @@ namespace EMotionFX { LmbrCentral::AttachmentComponentRequestBus::Event(attachment, &LmbrCentral::AttachmentComponentRequestBus::Events::Reattach, true); } - - // Send general mesh creation notification to interested parties. - LmbrCentral::MeshComponentNotificationBus::Event(GetEntityId(), &LmbrCentral::MeshComponentNotifications::OnMeshCreated, m_actorAsset); } } //namespace Integration } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/CanDeleteAnimGraphNode.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/CanDeleteAnimGraphNode.cpp index a7f9ae228f..c7b2363ad4 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/CanDeleteAnimGraphNode.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/CanDeleteAnimGraphNode.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -64,8 +65,10 @@ namespace EMotionFX { m_blendGraphWidget->OnContextMenuEvent(m_blendGraphWidget, localPoint, m_blendGraphWidget->LocalToGlobal(localPoint), m_animGraphPlugin, m_blendGraphWidget->GetActiveGraph()->GetSelectedAnimGraphNodes(), true, false, m_animGraphPlugin->GetActionFilter()); // Find Action for deleting node - QAction* deleteAction = GetNamedAction(m_blendGraphWidget, "Delete Node"); - ASSERT_TRUE(deleteAction) << "Could not find the 'Delete Node' action in the context menu"; + QAction* deleteAction = GetNamedAction(m_animGraphPlugin->GetViewWidget(), FromStdString(EMStudio::AnimGraphPlugin::s_deleteSelectedNodesShortcutName)); + ASSERT_TRUE(deleteAction) << "Could not find the '" << + std::string(EMStudio::AnimGraphPlugin::s_deleteSelectedNodesShortcutName.data(), EMStudio::AnimGraphPlugin::s_deleteSelectedNodesShortcutName.size()) + << "' action in the context menu"; // Trigger delete const size_t nodeCount = activeAnimGraph->GetNumNodes(); diff --git a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/Transitions/RemoveTransition.cpp b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/Transitions/RemoveTransition.cpp index 819c24baa7..98fec0fe13 100644 --- a/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/Transitions/RemoveTransition.cpp +++ b/Gems/EMotionFX/Code/Tests/ProvidesUI/AnimGraph/Transitions/RemoveTransition.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "qtestsystem.h" @@ -80,9 +81,8 @@ namespace EMotionFX ASSERT_TRUE(modelIndex.isValid()) << "Anim graph transition has an invalid model index."; animGraphModel.GetSelectionModel().select(QItemSelection(modelIndex, modelIndex), QItemSelectionModel::Current | QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); - // Delete key pressed. - EMStudio::BlendGraphWidget* blendGraphWidget = animGraphPlugin->GetGraphWidget(); - QTest::keyClick((QWidget*)blendGraphWidget, Qt::Key_Delete); + EMStudio::BlendGraphViewWidget* blendGraphViewWidget = animGraphPlugin->GetViewWidget(); + blendGraphViewWidget->GetAction(EMStudio::BlendGraphViewWidget::EDIT_DELETE)->trigger(); // Check if the transition get deleted. ASSERT_EQ(0, m_animGraph->GetRootStateMachine()->GetNumTransitions()) << " Anim Graph transition should be removed"; diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp index 770e1190be..7b15d6680d 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -518,18 +517,6 @@ namespace ImGui ImGui::EndChild(); // End the "Meshes in Scene" Child } } - - // Check to make sure the Tick Bus Connection status matches the debug enabled flag - if (m_meshDebugEnabled && !AZ::TickBus::Handler::BusIsConnected()) - { - // Connect to the Tick Bus - AZ::TickBus::Handler::BusConnect(); - } - else if (!m_meshDebugEnabled && AZ::TickBus::Handler::BusIsConnected()) - { - // Disconnect from the Tick Bus - AZ::TickBus::Handler::BusDisconnect(); - } } // Mesh Mouse Over Helper function @@ -597,81 +584,6 @@ namespace ImGui instanceOptions.m_mousedOverForDraw |= ImGui::IsItemHovered(); } - void ImGuiLYAssetExplorer::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) - { - // Search through all entities for Asset Components - OnTick_FindAssets(); - - // Check for all relevant pointers here. ( Actually requires checking all of these for different edge cases! :( - if (gEnv && gEnv->pRenderer && gEnv->pSystem && - gEnv->pSystem->GetIViewSystem() && gEnv->pSystem->GetIViewSystem()->GetActiveView() && - gEnv->pSystem->GetIViewSystem()->GetActiveView()->GetCurrentParams()) - { - // Get the Camera View Position from the view system. - const Vec3& cameraPosVec3 = gEnv->pSystem->GetIViewSystem()->GetActiveView()->GetCurrentParams()->position; - const AZ::Vector3 cameraPos(cameraPosVec3.x, cameraPosVec3.y, cameraPosVec3.z); - - // Loop through all Meshes to draw the appropriate ones! - for (const MeshInstanceDisplayList& meshInstanceList : m_meshInstanceDisplayList) - { - // bunch of different ways to filter results. First check for Mesh and Instance Name Filters... - bool displayMesh = true; - if (m_meshNameFilter) - { - displayMesh &= meshInstanceList.m_passesFilter; - } - if (m_entityNameFilter) - { - displayMesh &= meshInstanceList.m_childrenPassFilter; - } - - // ..Mouse Overs and Selection Filters should override other filters, so do it after.. Mouse Over THEN Selection Filter for precedence. - if (m_anyMousedOverForDraw) - { - displayMesh = meshInstanceList.m_mousedOverForDraw || meshInstanceList.m_childMousedOverForDraw; - } - else if (m_selectionFilter) - { - displayMesh = meshInstanceList.m_selectedForDraw; - for (const auto& meshInstance : meshInstanceList.m_instanceOptionMap) - { - displayMesh |= meshInstance.second.m_selectedForDraw; - } - } - - if (displayMesh) - { - for (const auto& meshInstance : meshInstanceList.m_instanceOptionMap) - { - AZ::Data::Asset meshAsset; - LmbrCentral::MeshComponentRequestBus::EventResult(meshAsset, meshInstance.first, &LmbrCentral::MeshComponentRequests::GetMeshAsset); - // See if we pass name filter first.. - bool displayEntity = true; - if (m_entityNameFilter) - { - displayEntity = meshInstance.second.m_passesFilter; - } - - // ..Mouse Overs and Selection Filters should override other filters, so do it after.. Mouse Over THEN Selection Filter for precedence. - if (m_anyMousedOverForDraw) - { - displayEntity = meshInstance.second.m_mousedOverForDraw || meshInstanceList.m_mousedOverForDraw; - } - else if (m_selectionFilter) - { - displayEntity = meshInstance.second.m_selectedForDraw | meshInstanceList.m_selectedForDraw; - } - - if (displayEntity) - { - OnTick_DrawEntity(meshInstance.first, meshAsset.GetId(), gEnv->pRenderer, cameraPos); - } - } - } - } - } - } - MeshInstanceDisplayList& ImGuiLYAssetExplorer::FindOrCreateMeshInstanceList(const char* meshName) { // Walk the list and see if an entry for this mesh exists already. If we find one, return it! @@ -696,250 +608,6 @@ namespace ImGui m_meshInstanceDisplayList.push_back(meshList); return m_meshInstanceDisplayList.back(); } - - // Scan the scene for Meshes! - void ImGuiLYAssetExplorer::OnTick_FindAssets() - { - // Retrieve Id map from game entity context (editor->runtime). - AzFramework::EntityContextId gameContextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::GameEntityContextRequestBus::BroadcastResult(gameContextId, &AzFramework::GameEntityContextRequests::GetGameEntityContextId); - - // Get the Root Slice Component - AZ::SliceComponent* rootSliceComponent; - AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(rootSliceComponent, gameContextId, - &AzFramework::SliceEntityOwnershipServiceRequests::GetRootSlice); - - if (rootSliceComponent) - { - // Get an unordered_set of all EntityIds in the slice - AZ::SliceComponent::EntityIdSet entityIds; - rootSliceComponent->GetEntityIds(entityIds); - - // Loop through Mesh Map and "un-verify" them - for (MeshInstanceDisplayList& meshInstanceList : m_meshInstanceDisplayList) - { - for (auto& meshInstance : meshInstanceList.m_instanceOptionMap) - { - meshInstance.second.m_verifiedThisFrame = false; - } - } - - for (auto it = entityIds.begin(); it != entityIds.end(); it++) - { - AZ::Data::Asset meshAsset; - LmbrCentral::MeshComponentRequestBus::EventResult(meshAsset, *it, &LmbrCentral::MeshComponentRequests::GetMeshAsset); - - if (meshAsset.IsReady()) - { - // Get the Asset Info so we can get the mesh path - AZ::Data::AssetInfo assetInfo; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, meshAsset.GetId()); - - AZStd::string meshPath = assetInfo.m_relativePath; - AZStd::to_lower(meshPath.begin(), meshPath.end()); - // Save off this mesh instance into the instance map - MeshInstanceDisplayList& displayList = FindOrCreateMeshInstanceList(meshPath.c_str()); - if (!displayList.m_instanceOptionMap.count(*it)) - { - // Get the Entity Name, for easy searching later - AZStd::string entityName; - AZ::ComponentApplicationBus::BroadcastResult(entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, *it); - - // Init the instance entry and options - MeshInstanceOptions& meshOptions = displayList.m_instanceOptionMap[*it]; - meshOptions.m_verifiedThisFrame = true; - meshOptions.m_passesFilter = true; - meshOptions.m_selectedForDraw = false; - meshOptions.m_mousedOverForDraw = false; - meshOptions.m_instanceLabel = AZStd::string::format("%s%s", (*it).ToString().c_str(), entityName.c_str()); - AZStd::to_lower(meshOptions.m_instanceLabel.begin(), meshOptions.m_instanceLabel.end()); - } - else - { - displayList.m_instanceOptionMap[*it].m_verifiedThisFrame = true; - } - } - } - - // Loop through Mesh Map again and remove any "un-verify"-ed entries! - for (auto meshInstanceListIter = m_meshInstanceDisplayList.begin(); meshInstanceListIter != m_meshInstanceDisplayList.end();) - { - for (auto meshInstanceIter = (*meshInstanceListIter).m_instanceOptionMap.begin(); meshInstanceIter != (*meshInstanceListIter).m_instanceOptionMap.end();) - { - if (!(*meshInstanceIter).second.m_verifiedThisFrame) - { - // erase this instance from the map and set the iterator correctly. - meshInstanceIter = (*meshInstanceListIter).m_instanceOptionMap.erase(meshInstanceIter); - } - else - { - // increment the iterator - meshInstanceIter++; - } - } - - // Remove the Mesh Entry if there are no instances remaining - if ((*meshInstanceListIter).m_instanceOptionMap.empty()) - { - meshInstanceListIter = m_meshInstanceDisplayList.erase(meshInstanceListIter); - } - else - { - // increment the iterator - meshInstanceListIter++; - } - } - } - } - - // We know we want to draw this Entity/Mesh ( depending on distance from Cam ).. so draw! - void ImGuiLYAssetExplorer::OnTick_DrawEntity(const AZ::EntityId& entity, const AZ::Data::AssetId& assetId, IRenderer* renderer, const AZ::Vector3& cameraPos) - { - // Get the Entity Position so we can see how far from the camera we are. - AZ::Vector3 worldPos = AZ::Vector3::CreateZero(); - AZ::TransformBus::EventResult(worldPos, entity, &AZ::TransformBus::Events::GetWorldTranslation); - - // Get Our Distance From The Camera! ( Used just for draw alpha value ) - float distFromCamera = m_distanceFilter_far + 1.0f; // Default to just outside camera view ( i.e. Don't draw ) - if (m_anyMousedOverForDraw || m_selectionFilter || !m_distanceFilter) - { - // If we have either the Selection Filter or Mouse Over state on or the distance filter is off, and we made it this far, we are the lucky selected one! Draw ourselves by setting dist to 0.0f - distFromCamera = 0.0; - } - else if (m_distanceFilter) - { - // Distance filter is on and we aren't selected, so actually find the distance from the camera - distFromCamera = worldPos.GetDistance(cameraPos); - } - - // Only draw things within view distance ( cheese it to zero above to force drawing far things ) - if (distFromCamera <= m_distanceFilter_far) - { - // Find an interpolated Alpha.. 1.0f while inside near radius, interp 1.0 -> 0.0 while heading toward far radius - float alpha = (distFromCamera <= m_distanceFilter_near) ? 1.0f : (1.0f - ((distFromCamera - m_distanceFilter_near) / (m_distanceFilter_far - m_distanceFilter_near))); - - // The string to hold label text we will build. - AZStd::string entityLabel; - - // Grab the Asset Info to get the mesh path name. - AZ::Data::AssetInfo assetInfo; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, assetId); - - // Start the label with either the EntName and Mesh, or just Mesh - if (m_inWorld_label_entityName) - { - AZ::ComponentApplicationBus::BroadcastResult(entityLabel, &AZ::ComponentApplicationBus::Events::GetEntityName, entity); - entityLabel = AZStd::string::format("Entity: %s %s\nMesh: %s", entity.ToString().c_str(), entityLabel.c_str(), assetInfo.m_relativePath.c_str()); - } - else - { - entityLabel = AZStd::string::format("Mesh: %s", assetInfo.m_relativePath.c_str()); - } - - // See if we should add the Material! - if (m_inWorld_label_materialName) - { - _smart_ptr material; - LmbrCentral::MaterialOwnerRequestBus::EventResult(material, entity, &LmbrCentral::MaterialOwnerRequests::GetMaterial); - if (material) - { - entityLabel.append(AZStd::string::format("\nMaterial: %s", material->GetName())); - } - } - - // Get The Render Node for mesh debug draw and Lod Info - IRenderNode* renderNode = nullptr; - LmbrCentral::RenderNodeRequestBus::EventResult(renderNode, entity, &LmbrCentral::RenderNodeRequests::GetRenderNode); - - if (renderNode != nullptr && renderNode->GetEntityStatObj()) - { - // Debug Draw Mesh - if (m_inWorld_debugDrawMesh) - { - SGeometryDebugDrawInfo dd; - dd.color.Set(0.0f, 0.0f, 255.0f, 0.5f * alpha); - dd.lineColor.Set(255.0f, 0.0f, 0.0f, 0.75f * alpha); - renderNode->GetEntityStatObj()->DebugDraw(dd, 0.2f); - } - // Draw Total Lods info - if (m_inWorld_label_totalLods) - { - entityLabel.append(AZStd::string::format("\nTotal Lods: %d", renderNode->GetEntityStatObj()->GetLoadedLodsNum())); - } - // Draw Misc Lod Info - if (m_inWorld_label_miscLod) - { - entityLabel.append(AZStd::string::format("\nFirst Lod Distance: %f", renderNode->GetFirstLodDistance())); - float distances[SMeshLodInfo::s_nMaxLodCount]; - renderNode->GetLodDistances(gEnv->p3DEngine->GetFrameLodInfo(), distances); - for (int i = 0; i < SMeshLodInfo::s_nMaxLodCount; i++) - { - entityLabel.append(AZStd::string::format("\n frameLod: %d - %f", i, distances[i])); - } - } - } - - // Draw the label in the world - if (m_inWorld_drawLabel) - { - SDrawTextInfo ti; - ti.xscale = ti.yscale = m_inWorld_labelTextSize * alpha; - ti.flags = eDrawText_FixedSize | eDrawText_Center | eDrawText_800x600; - if (m_inWorld_label_framed) - { - ti.flags |= eDrawText_Framed; - } - if (m_inWorld_label_monoSpace) - { - ti.flags |= eDrawText_Monospace; - } - - { - ti.color[0] = m_inWorld_label_textColor.Value.x; - ti.color[1] = m_inWorld_label_textColor.Value.y; - ti.color[2] = m_inWorld_label_textColor.Value.z; - ti.color[3] = alpha; - } - Vec3 labelPos(worldPos.GetX(), worldPos.GetY(), worldPos.GetZ() - m_inWorld_originSphereRadius); - renderer->DrawTextQueued(labelPos, ti, entityLabel.c_str()); - } - - // Draw the sphere and/or AABB in the world - if (m_inWorld_drawOriginSphere || m_inWorld_drawAABB) - { - IRenderAuxGeom* pAuxGeom = renderer->GetIRenderAuxGeom(); - if (pAuxGeom) - { - const ColorF sphereColor(m_inWorld_label_textColor.Value.x, m_inWorld_label_textColor.Value.y, m_inWorld_label_textColor.Value.z, alpha); - Vec3 spherePos(worldPos.GetX(), worldPos.GetY(), worldPos.GetZ()); - - // draw a sample sphere - SAuxGeomRenderFlags oldFlags = pAuxGeom->GetRenderFlags(); - SAuxGeomRenderFlags flags = oldFlags; - flags.SetDepthWriteFlag(e_DepthWriteOff); - flags.SetDepthTestFlag(e_DepthTestOff); - flags.SetDrawInFrontMode(e_DrawInFrontOn); - flags.SetFillMode(e_FillModeSolid); - flags.SetCullMode(e_CullModeNone); - pAuxGeom->SetRenderFlags(flags); - - if ( m_inWorld_drawOriginSphere) - { - pAuxGeom->DrawSphere(spherePos, m_inWorld_originSphereRadius, sphereColor, false); - } - - if (m_inWorld_drawAABB && renderNode) - { - pAuxGeom->DrawAABB(renderNode->GetBBox(), false, sphereColor, EBoundingBoxDrawStyle::eBBD_Extremes_Color_Encoded); - } - - // Restore rendering state - pAuxGeom->SetRenderFlags(oldFlags); - } - } - } - } - -} // namespace ImGui + } // namespace ImGui #endif // IMGUI_ENABLED diff --git a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.h b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.h index 29584c84d3..b5f8ea576c 100644 --- a/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.h +++ b/Gems/ImGui/Code/Source/LYCommonMenu/ImGuiLYAssetExplorer.h @@ -43,7 +43,6 @@ namespace ImGui class ImGuiLYAssetExplorer : public ImGuiAssetExplorerRequestBus::Handler - , public AZ::TickBus::Handler { public: @@ -61,10 +60,6 @@ namespace ImGui void SetEnabled(bool enabled) override { m_enabled = enabled; m_meshDebugEnabled = enabled; } // -- ImGuiAssetExplorerRequestBus::Handler Interface ---------------------- - // -- AZ::TickBus::Handler Interface --------------------------------------- - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - // -- AZ::TickBus::Handler Interface --------------------------------------- - // Toggle the menu on and off void ToggleEnabled() { m_enabled = !m_enabled; } @@ -117,9 +112,6 @@ namespace ImGui void ImGuiUpdate_DrawMeshMouseOver(MeshInstanceDisplayList& meshDisplayList); void ImGuiUpdate_DrawEntityInstanceMouseOver(MeshInstanceDisplayList& meshDisplayList, AZ::EntityId& entityInstance, AZStd::string& entityName, MeshInstanceOptions& instanceOptions); - // Helper functions for the OnTick callback - void OnTick_DrawEntity(const AZ::EntityId& entity, const AZ::Data::AssetId& assetId, IRenderer* renderer, const AZ::Vector3& cameraPos); - void OnTick_FindAssets(); }; } #endif // IMGUI_ENABLED diff --git a/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.cpp b/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.cpp deleted file mode 100644 index 537585f48c..0000000000 --- a/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.cpp +++ /dev/null @@ -1,349 +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 "LmbrCentral_precompiled.h" -#include "AttachmentComponent.h" -#include -#include -#include -#include -#include -#include - -namespace LmbrCentral -{ - /// Behavior Context handler for AttachmentComponentNotificationBus - class BehaviorAttachmentComponentNotificationBusHandler : public AttachmentComponentNotificationBus::Handler, public AZ::BehaviorEBusHandler - { - public: - AZ_EBUS_BEHAVIOR_BINDER(BehaviorAttachmentComponentNotificationBusHandler, "{636B95A0-5C7D-4EE7-8645-955665315451}", AZ::SystemAllocator - , OnAttached, OnDetached); - - void OnAttached(AZ::EntityId id) override - { - Call(FN_OnAttached, id); - } - - void OnDetached(AZ::EntityId id) override - { - Call(FN_OnDetached, id); - } - }; - - void AttachmentConfiguration::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Target ID", &AttachmentConfiguration::m_targetId) - ->Field("Target Bone Name", &AttachmentConfiguration::m_targetBoneName) - ->Field("Target Offset", &AttachmentConfiguration::m_targetOffset) - ->Field("Attached Initially", &AttachmentConfiguration::m_attachedInitially) - ->Field("Scale Source", &AttachmentConfiguration::m_scaleSource) - ; - } - AZ::BehaviorContext* behaviorContext = azrtti_cast(context); - if (behaviorContext) - { - behaviorContext->EBus("AttachmentComponentRequestBus") - ->Event("Attach", &AttachmentComponentRequestBus::Events::Attach) - ->Event("Detach", &AttachmentComponentRequestBus::Events::Detach) - ->Event("SetAttachmentOffset", &AttachmentComponentRequestBus::Events::SetAttachmentOffset); - - behaviorContext->EBus("AttachmentComponentNotificationBus") - ->Handler(); - } - } - - void AttachmentComponent::Reflect(AZ::ReflectContext* context) - { - AttachmentConfiguration::Reflect(context); - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Configuration", &AttachmentComponent::m_initialConfiguration) - ; - } - } - - //========================================================================= - // BoneFollower - //========================================================================= - - void BoneFollower::Activate(AZ::Entity* owner, const AttachmentConfiguration& configuration, bool targetCanAnimate) - { - AZ_Assert(owner, "owner is required"); - AZ_Assert(!m_ownerId.IsValid(), "BoneFollower is already Activated"); - - m_ownerId = owner->GetId(); - m_targetCanAnimate = targetCanAnimate; - m_isUpdatingOwnerTransform = false; - m_scaleSource = configuration.m_scaleSource; - - m_cachedOwnerTransform = AZ::Transform::CreateIdentity(); - EBUS_EVENT_ID_RESULT(m_cachedOwnerTransform, m_ownerId, AZ::TransformBus, GetWorldTM); - - if (configuration.m_attachedInitially) - { - Attach(configuration.m_targetId, configuration.m_targetBoneName.c_str(), configuration.m_targetOffset); - } - - AttachmentComponentRequestBus::Handler::BusConnect(m_ownerId); - } - - void BoneFollower::Deactivate() - { - AZ_Assert(m_ownerId.IsValid(), "BoneFollower was never Activated"); - - AttachmentComponentRequestBus::Handler::BusDisconnect(); - Detach(); - m_ownerId.SetInvalid(); - } - - AZ::EntityId BoneFollower::GetTargetEntityId() - { - return m_targetId; - } - - AZ::Transform BoneFollower::GetOffset() - { - return m_targetOffset; - } - - void BoneFollower::Attach(AZ::EntityId targetId, const char* targetBoneName, const AZ::Transform& offset) - { - AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use.") - - // safe to try and detach, even if we weren't attached - Detach(); - - if (!targetId.IsValid()) - { - return; - } - - if (targetId == m_ownerId) - { - AZ_Error("Attachment Component", false, "AttachmentComponent cannot target itself"); - return; - } - - // Note: the target entity may not be activated yet. That's ok. - // When mesh is ready we are notified via MeshComponentEvents::OnMeshCreated - // When transform is ready we are notified via TransformNotificationBus::OnTransformChanged - - m_targetId = targetId; - m_targetBoneName = targetBoneName; - m_targetOffset = offset; - - BindTargetBone(); - - m_targetBoneTransform = AZ::Transform::Identity(); - - m_isTargetEntityTransformKnown = false; // target's transform may not be available yet - - AZ::TransformBus::EventResult(m_cachedOwnerTransform, m_ownerId, &AZ::TransformBus::Events::GetWorldTM); // owner query will always succeed - - MeshComponentNotificationBus::Handler::BusConnect(m_targetId); // fires OnMeshCreated if asset is already ready - AZ::TransformNotificationBus::Handler::BusConnect(m_targetId); - if (m_targetCanAnimate) - { - // Only register for per-frame updates when target can animate - AZ::TickBus::Handler::BusConnect(); - } - - // update owner's transform - UpdateOwnerTransformIfNecessary(); - - // alert others that we've attached - AttachmentComponentNotificationBus::Event(m_targetId, &AttachmentComponentNotificationBus::Events::OnAttached, m_ownerId); - } - - void BoneFollower::Detach() - { - AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use."); - - if (m_targetId.IsValid()) - { - // alert others that we're detaching - EBUS_EVENT_ID(m_targetId, AttachmentComponentNotificationBus, OnDetached, m_ownerId); - - MeshComponentNotificationBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(m_targetId); - AZ::TickBus::Handler::BusDisconnect(); - - m_targetId.SetInvalid(); - } - } - - const char* BoneFollower::GetJointName() - { - return m_targetBoneName.c_str(); - } - - void BoneFollower::SetAttachmentOffset(const AZ::Transform& offset) - { - AZ_Assert(m_ownerId.IsValid(), "BoneFollower must be Activated to use."); - - if (m_targetId.IsValid()) - { - m_targetOffset = offset; - UpdateOwnerTransformIfNecessary(); - } - } - - void BoneFollower::OnMeshCreated(const AZ::Data::Asset& asset) - { - (void)asset; - - // reset character values - BindTargetBone(); - m_targetBoneTransform = QueryBoneTransform(); - - // move owner if necessary - UpdateOwnerTransformIfNecessary(); - } - - void BoneFollower::BindTargetBone() - { - m_targetBoneId = -1; - SkeletalHierarchyRequestBus::EventResult(m_targetBoneId, m_targetId, &SkeletalHierarchyRequests::GetJointIndexByName, m_targetBoneName.c_str()); - } - - void BoneFollower::UpdateOwnerTransformIfNecessary() - { - // Can't update until target entity's transform is known - if (!m_isTargetEntityTransformKnown) - { - if (AZ::TransformBus::GetNumOfEventHandlers(m_targetId) == 0) - { - return; - } - - AZ::TransformBus::EventResult(m_targetEntityTransform, m_targetId, &AZ::TransformBus::Events::GetWorldTM); - m_isTargetEntityTransformKnown = true; - } - - AZ::Transform finalTransform; - if (m_scaleSource == AttachmentConfiguration::ScaleSource::WorldScale) - { - // apply offset in world-space - finalTransform = m_targetEntityTransform * m_targetBoneTransform; - finalTransform.SetScale(AZ::Vector3::CreateOne()); - finalTransform *= m_targetOffset; - } - else if (m_scaleSource == AttachmentConfiguration::ScaleSource::TargetEntityScale) - { - // apply offset in target-entity-space (ignoring bone scale) - AZ::Transform boneNoScale = m_targetBoneTransform; - boneNoScale.SetScale(AZ::Vector3::CreateOne()); - - finalTransform = m_targetEntityTransform * boneNoScale * m_targetOffset; - } - else // AttachmentConfiguration::ScaleSource::TargetEntityScale - { - // apply offset in target-bone-space - finalTransform = m_targetEntityTransform * m_targetBoneTransform * m_targetOffset; - } - - if (m_cachedOwnerTransform != finalTransform) - { - AZ_Warning("Attachment Component", !m_isUpdatingOwnerTransform, "AttachmentComponent detected a cycle when updating transform, do not target child entities."); - if (!m_isUpdatingOwnerTransform) - { - m_cachedOwnerTransform = finalTransform; - m_isUpdatingOwnerTransform = true; - EBUS_EVENT_ID(m_ownerId, AZ::TransformBus, SetWorldTM, finalTransform); - m_isUpdatingOwnerTransform = false; - } - } - } - - AZ::Transform BoneFollower::QueryBoneTransform() const - { - AZ::Transform boneTransform = AZ::Transform::CreateIdentity(); - - if (m_targetBoneId >= 0) - { - SkeletalHierarchyRequestBus::EventResult(boneTransform, m_targetId, &SkeletalHierarchyRequests::GetJointTransformCharacterRelative, m_targetBoneId); - } - - return boneTransform; - } - - // fires when target's transform changes - void BoneFollower::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) - { - m_targetEntityTransform = world; - m_isTargetEntityTransformKnown = true; - UpdateOwnerTransformIfNecessary(); - } - - void BoneFollower::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) - { - m_targetBoneTransform = QueryBoneTransform(); - UpdateOwnerTransformIfNecessary(); - } - - int BoneFollower::GetTickOrder() - { - return AZ::TICK_ATTACHMENT; - } - - void BoneFollower::Reattach(bool detachFirst) - { -#ifdef AZ_ENABLE_TRACING - AZ::Entity* ownerEntity = nullptr; - AZ::Entity* targetEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(ownerEntity, &AZ::ComponentApplicationBus::Events::FindEntity, m_ownerId); - AZ::ComponentApplicationBus::BroadcastResult(targetEntity, &AZ::ComponentApplicationBus::Events::FindEntity, m_targetId); - AZ_TracePrintf("BoneFollower", "Reattaching entity '%s' to entity '%s'", ownerEntity ? ownerEntity->GetName().c_str() : "", - targetEntity ? targetEntity->GetName().c_str() : ""); -#endif - - if (m_targetId.IsValid() && detachFirst) - { - AttachmentComponentNotificationBus::Event(m_targetId, &AttachmentComponentNotificationBus::Events::OnDetached, m_ownerId); - } - - if (m_targetId != m_ownerId) - { - AttachmentComponentNotificationBus::Event(m_targetId, &AttachmentComponentNotificationBus::Events::OnAttached, m_ownerId); - } - } - - //========================================================================= - // AttachmentComponent - //========================================================================= - - void AttachmentComponent::Activate() - { -#ifdef AZ_ENABLE_TRACING - bool isStaticTransform = false; - AZ::TransformBus::EventResult(isStaticTransform, GetEntityId(), &AZ::TransformBus::Events::IsStaticTransform); - AZ_Warning("Attachment Component", !isStaticTransform, - "Attachment needs to move, but entity '%s' %s has a static transform.", GetEntity()->GetName().c_str(), GetEntityId().ToString().c_str()); -#endif - - m_boneFollower.Activate(GetEntity(), m_initialConfiguration, true); - } - - - void AttachmentComponent::Deactivate() - { - m_boneFollower.Deactivate(); - } -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.h b/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.h deleted file mode 100644 index f2ef428ac2..0000000000 --- a/Gems/LmbrCentral/Code/Source/Animation/AttachmentComponent.h +++ /dev/null @@ -1,186 +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 -#include -#include -#include -#include - -struct ISkeletonPose; - -namespace LmbrCentral -{ - /*! - * Configuration data for AttachmentComponent. - */ - struct AttachmentConfiguration - { - AZ_TYPE_INFO(AttachmentConfiguration, "{74B5DC69-DE44-4640-836A-55339E116795}"); - - virtual ~AttachmentConfiguration() = default; - - static void Reflect(AZ::ReflectContext* context); - - //! Attach to this entity. - AZ::EntityId m_targetId; - - //! Attach to this bone on target entity. - AZStd::string m_targetBoneName; - - //! Offset from target. - AZ::Transform m_targetOffset = AZ::Transform::Identity(); - - //! Whether to attach to target upon activation. - //! If false, the entity remains detached until Attach() is called. - bool m_attachedInitially = true; - - //! Source from which to retrieve scale information. - enum class ScaleSource : AZ::u8 - { - WorldScale, // Scaled in world space. - TargetEntityScale, // Adopt scaling of attachment target entity. - TargetBoneScale, // Adopt scaling of attachment target entity/joint. - }; - ScaleSource m_scaleSource = ScaleSource::WorldScale; - }; - - /* - * Common functionality for game and editor attachment components. - * The BoneFollower tracks movement of the target's bone and - * updates the owning entity's TransformComponent to follow. - * This class should be a member within the attachment component - * and be activated/deactivated along with the component. - * \ref AttachmentComponent - */ - class BoneFollower - : public AttachmentComponentRequestBus::Handler - , public AZ::TransformNotificationBus::Handler - , public MeshComponentNotificationBus::Handler - , public AZ::Data::AssetBus::Handler - , public AZ::TickBus::Handler - { - public: - void Activate(AZ::Entity* owner, const AttachmentConfiguration& initialConfiguration, bool targetCanAnimate); - void Deactivate(); - - //////////////////////////////////////////////////////////////////////// - // AttachmentComponentRequests - void Reattach(bool detachFirst); - void Attach(AZ::EntityId targetId, const char* targetBoneName, const AZ::Transform& offset) override; - void Detach() override; - void SetAttachmentOffset(const AZ::Transform& offset) override; - const char* GetJointName() override; - AZ::EntityId GetTargetEntityId() override; - AZ::Transform GetOffset() override; - //////////////////////////////////////////////////////////////////////// - - private: - - //////////////////////////////////////////////////////////////////////// - // AZ::TickBus - //! Check target bone transform every frame. - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - //! Make sure target bone transform updates after animation update. - int GetTickOrder() override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AZ::TransformNotificationBus - //! When target's transform changes - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // MeshComponentEvents - //! When target's mesh changes - void OnMeshCreated(const AZ::Data::Asset& asset) override; - //////////////////////////////////////////////////////////////////////// - - void BindTargetBone(); - - AZ::Transform QueryBoneTransform() const; - - void UpdateOwnerTransformIfNecessary(); - - //! Entity which which is being attached. - AZ::EntityId m_ownerId; - - //! Whether to query bone position per-frame (false while in editor) - bool m_targetCanAnimate = false; - - AZ::EntityId m_targetId; - AZStd::string m_targetBoneName; - AZ::Transform m_targetOffset; //!< local transform - AZ::Transform m_targetBoneTransform; //!< local transform of bone - AZ::Transform m_targetEntityTransform; //!< world transform of target - bool m_isTargetEntityTransformKnown = false; - - //! Cached value, so we don't update owner's position unnecessarily. - AZ::Transform m_cachedOwnerTransform; - bool m_isUpdatingOwnerTransform = false; //!< detect infinite loops when updating owner's transform - - // Cached character values to avoid repeated lookup. - // These are set by calling ResetCharacter() - int m_targetBoneId; //!< negative when bone not found - - AttachmentConfiguration::ScaleSource m_scaleSource; - }; - - /*! - * The AttachmentComponent lets an entity stick to a particular bone on - * a target entity. This is achieved by tracking movement of the target's - * bone and updating the entity's TransformComponent accordingly. - */ - class AttachmentComponent - : public AZ::Component - { - public: - AZ_COMPONENT(AttachmentComponent, "{2D17A64A-7AC5-4C02-AC36-C5E8141FFDDF}"); - - friend class EditorAttachmentComponent; - - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("AttachmentService", 0x5aaa7b63)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("AttachmentService", 0x5aaa7b63)); - } - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - ~AttachmentComponent() override = default; - - private: - //////////////////////////////////////////////////////////////////////// - // AZ::Component - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - //! Initial configuration for m_attachment - AttachmentConfiguration m_initialConfiguration; - - //! Implements actual attachment functionality - BoneFollower m_boneFollower; - }; -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.cpp b/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.cpp deleted file mode 100644 index 265f4ad864..0000000000 --- a/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.cpp +++ /dev/null @@ -1,238 +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 "LmbrCentral_precompiled.h" -#include "EditorAttachmentComponent.h" -#include -#include -#include -#include - -namespace LmbrCentral -{ - void EditorAttachmentComponent::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Target ID", &EditorAttachmentComponent::m_targetId) - ->Field("Target Bone Name", &EditorAttachmentComponent::m_targetBoneName) - ->Field("Position Offset", &EditorAttachmentComponent::m_positionOffset) - ->Field("Rotation Offset", &EditorAttachmentComponent::m_rotationOffset) - ->Field("Scale Offset", &EditorAttachmentComponent::m_scaleOffset) - ->Field("Attached Initially", &EditorAttachmentComponent::m_attachedInitially) - ->Field("Scale Source", &EditorAttachmentComponent::m_scaleSource) - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - if (editContext) - { - editContext->Class( - "Attachment", "The Attachment component lets an entity attach to a bone on the skeleton of another entity") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Animation") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Attachment.svg") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/Attachment.png") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-attachment.html") - ->DataElement(0, &EditorAttachmentComponent::m_targetId, - "Target entity", "Attach to this entity.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetIdChanged) - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &EditorAttachmentComponent::m_targetBoneName, - "Joint name", "Attach to this joint on target entity.") - ->Attribute(AZ::Edit::Attributes::StringList, &EditorAttachmentComponent::GetTargetBoneOptions) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetBoneChanged) - ->DataElement(0, &EditorAttachmentComponent::m_positionOffset, - "Position offset", "Local position offset from target bone") - ->Attribute(AZ::Edit::Attributes::Suffix, "m") - ->Attribute(AZ::Edit::Attributes::Step, 0.01f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) - ->DataElement(0, &EditorAttachmentComponent::m_rotationOffset, - "Rotation offset", "Local rotation offset from target bone") - ->Attribute(AZ::Edit::Attributes::Suffix, "deg") - ->Attribute(AZ::Edit::Attributes::Step, 0.01f) - ->Attribute(AZ::Edit::Attributes::Min, -AZ::RadToDeg(AZ::Constants::TwoPi)) - ->Attribute(AZ::Edit::Attributes::Max, AZ::RadToDeg(AZ::Constants::TwoPi)) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) - ->DataElement(0, &EditorAttachmentComponent::m_scaleOffset, - "Scale offset", "Local scale offset from target entity") - ->Attribute(AZ::Edit::Attributes::Step, 0.1f) - ->Attribute(AZ::Edit::Attributes::Min, 0.001f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnTargetOffsetChanged) - ->DataElement(0, &EditorAttachmentComponent::m_attachedInitially, - "Attached initially", "Whether to attach to target upon activation.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnAttachedInitiallyChanged) - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &EditorAttachmentComponent::m_scaleSource, - "Scaling", "How object scale should be determined. " - "Use world scale = Attached object is scaled in world space, Use target entity scale = Attached object adopts scale of target entity., Use target bone scale = Attached object adopts scale of target entity/joint.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorAttachmentComponent::OnScaleSourceChanged) - ->EnumAttribute(AttachmentConfiguration::ScaleSource::WorldScale, "Use world scale") - ->EnumAttribute(AttachmentConfiguration::ScaleSource::TargetEntityScale, "Use target entity scale") - ->EnumAttribute(AttachmentConfiguration::ScaleSource::TargetBoneScale, "Use target bone scale") - ; - } - } - } - - void EditorAttachmentComponent::Activate() - { - Base::Activate(); - m_boneFollower.Activate(GetEntity(), - CreateAttachmentConfiguration(), - false); // Entity's don't animate in Editor - } - - void EditorAttachmentComponent::Deactivate() - { - m_boneFollower.Deactivate(); - Base::Deactivate(); - } - - void EditorAttachmentComponent::BuildGameEntity(AZ::Entity* gameEntity) - { - AttachmentComponent* component = gameEntity->CreateComponent(); - if (component) - { - component->m_initialConfiguration = CreateAttachmentConfiguration(); - } - } - - AttachmentConfiguration EditorAttachmentComponent::CreateAttachmentConfiguration() const - { - AttachmentConfiguration configuration; - configuration.m_targetId = m_targetId; - configuration.m_targetBoneName = m_targetBoneName; - configuration.m_targetOffset = GetTargetOffset(); - configuration.m_attachedInitially = m_attachedInitially; - configuration.m_scaleSource = m_scaleSource; - return configuration; - } - - AZ::Transform EditorAttachmentComponent::GetTargetOffset() const - { - AZ::Transform offset = AZ::ConvertEulerDegreesToTransform(m_rotationOffset); - offset.SetTranslation(m_positionOffset); - offset.MultiplyByScale(m_scaleOffset); - return offset; - } - - AZStd::vector EditorAttachmentComponent::GetTargetBoneOptions() const - { - AZStd::vector names; - - // insert blank entry, so user may choose to bind to NO bone. - names.push_back(""); - - // track whether currently-set bone is found - bool currentTargetBoneFound = false; - - // Get character and iterate over bones - AZ::u32 jointCount = 0; - SkeletalHierarchyRequestBus::EventResult(jointCount, m_targetId, &SkeletalHierarchyRequests::GetJointCount); - for (AZ::u32 jointIndex = 0; jointIndex < jointCount; ++jointIndex) - { - const char* name = nullptr; - SkeletalHierarchyRequestBus::EventResult(name, m_targetId, &SkeletalHierarchyRequests::GetJointNameByIndex, jointIndex); - if (name) - { - names.push_back(name); - - if (!currentTargetBoneFound) - { - currentTargetBoneFound = (m_targetBoneName == names.back()); - } - } - } - - // If we never found currently-set bone name, - // stick it at top of list, just in case user wants to keep it anyway - if (!currentTargetBoneFound && !m_targetBoneName.empty()) - { - names.insert(names.begin(), m_targetBoneName); - } - - return names; - } - - AZ::u32 EditorAttachmentComponent::OnTargetIdChanged() - { - // Warn about bad setups (it won't crash, but it's nice to handle this early) - if (m_targetId == GetEntityId()) - { - AZ_Warning(GetEntity()->GetName().c_str(), false, "AttachmentComponent cannot target self.") - m_targetId.SetInvalid(); - } - - // Warn about children attaching to a parent - AZ::EntityId parentOfTarget; - AZ::TransformBus::EventResult(parentOfTarget, m_targetId, &AZ::TransformBus::Events::GetParentId); - while (parentOfTarget.IsValid()) - { - if (parentOfTarget == GetEntityId()) - { - AZ_Warning(GetEntity()->GetName().c_str(), parentOfTarget != GetEntityId(), "AttachmentComponent cannot target child entity"); - m_targetId.SetInvalid(); - break; - } - - AZ::EntityId currentParentId = parentOfTarget; - parentOfTarget.SetInvalid(); - AZ::TransformBus::EventResult(parentOfTarget, currentParentId, &AZ::TransformBus::Events::GetParentId); - } - - AttachOrDetachAsNecessary(); - - return AZ::Edit::PropertyRefreshLevels::AttributesAndValues; // refresh bone options - } - - AZ::u32 EditorAttachmentComponent::OnTargetBoneChanged() - { - AttachOrDetachAsNecessary(); - return AZ::Edit::PropertyRefreshLevels::None; - } - - AZ::u32 EditorAttachmentComponent::OnTargetOffsetChanged() - { - EBUS_EVENT_ID(GetEntityId(), AttachmentComponentRequestBus, SetAttachmentOffset, GetTargetOffset()); - return AZ::Edit::PropertyRefreshLevels::None; - } - - AZ::u32 EditorAttachmentComponent::OnAttachedInitiallyChanged() - { - AttachOrDetachAsNecessary(); - return AZ::Edit::PropertyRefreshLevels::None; - } - - AZ::u32 EditorAttachmentComponent::OnScaleSourceChanged() - { - m_boneFollower.Deactivate(); - m_boneFollower.Activate(GetEntity(), - CreateAttachmentConfiguration(), - false); - return AZ::Edit::PropertyRefreshLevels::None; - } - - void EditorAttachmentComponent::AttachOrDetachAsNecessary() - { - if (m_attachedInitially && m_targetId.IsValid()) - { - EBUS_EVENT_ID(GetEntityId(), AttachmentComponentRequestBus, Attach, m_targetId, m_targetBoneName.c_str(), GetTargetOffset()); - } - else - { - EBUS_EVENT_ID(GetEntityId(), AttachmentComponentRequestBus, Detach); - } - } -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.h b/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.h deleted file mode 100644 index 808ffd393e..0000000000 --- a/Gems/LmbrCentral/Code/Source/Animation/EditorAttachmentComponent.h +++ /dev/null @@ -1,101 +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 "AttachmentComponent.h" - -namespace LmbrCentral -{ - /*! - * In-editor attachment component. - * \ref AttachmentComponent - */ - class EditorAttachmentComponent - : public AzToolsFramework::Components::EditorComponentBase - { - private: - using Base = AzToolsFramework::Components::EditorComponentBase; - public: - AZ_COMPONENT(EditorAttachmentComponent, "{DA6072FD-E696-47D8-81D9-1F77D3464200}", Base); - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - AttachmentComponent::GetProvidedServices(provided); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - AttachmentComponent::GetIncompatibleServices(incompatible); - } - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - AttachmentComponent::GetRequiredServices(required); - } - - ~EditorAttachmentComponent() override = default; - void BuildGameEntity(AZ::Entity* gameEntity) override; - - protected: - - ////////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Activate() override; - void Deactivate() override; - ////////////////////////////////////////////////////////////////////////// - - AZ::u32 OnTargetIdChanged(); - AZ::u32 OnTargetBoneChanged(); - AZ::u32 OnTargetOffsetChanged(); - AZ::u32 OnAttachedInitiallyChanged(); - AZ::u32 OnScaleSourceChanged(); - - //! Invoked when an attachment property changes - void AttachOrDetachAsNecessary(); - - //! For populating ComboBox - AZStd::vector GetTargetBoneOptions() const; - - //! Create runtime configuration from editor configuration - AttachmentConfiguration CreateAttachmentConfiguration() const; - - //! Create AZ::Transform from position and rotation - AZ::Transform GetTargetOffset() const; - - //! Attach to this entity. - AZ::EntityId m_targetId; - - //! Attach to this bone on target entity. - AZStd::string m_targetBoneName; - - //! Offset from target bone's position. - AZ::Vector3 m_positionOffset = AZ::Vector3::CreateZero(); - - //! Offset from target bone's rotation. - AZ::Vector3 m_rotationOffset = AZ::Vector3::CreateZero(); - - //! Offset from target entity's scale. - AZ::Vector3 m_scaleOffset = AZ::Vector3::CreateOne(); - - //! Observe scale information from the specified source. - AttachmentConfiguration::ScaleSource m_scaleSource = AttachmentConfiguration::ScaleSource::WorldScale; - - //! Whether to attach to target upon activation. - //! If false, the entity remains detached until Attach() is called. - bool m_attachedInitially = true; - - //! Implements actual attachment functionality - LmbrCentral::BoneFollower m_boneFollower; - }; -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp b/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp index 974dddc6e0..ceac768e79 100644 --- a/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp +++ b/Gems/LmbrCentral/Code/Source/LmbrCentral.cpp @@ -21,7 +21,6 @@ #include // Component descriptors -#include "Animation/AttachmentComponent.h" #include "Audio/AudioAreaEnvironmentComponent.h" #include "Audio/AudioEnvironmentComponent.h" #include "Audio/AudioListenerComponent.h" @@ -33,7 +32,6 @@ #include "Audio/AudioSystemComponent.h" #include "Audio/AudioTriggerComponent.h" #include "Bundling/BundlingSystemComponent.h" -#include "Rendering/MeshComponent.h" #include "Ai/NavigationComponent.h" #include "Scripting/TagComponent.h" #include "Scripting/SimpleStateComponent.h" @@ -74,9 +72,6 @@ #include #include -// Asset handlers -#include - // Scriptable Ebus Registration #include "Events/ReflectScriptableEvents.h" @@ -194,7 +189,6 @@ namespace LmbrCentral : AZ::Module() { m_descriptors.insert(m_descriptors.end(), { - AttachmentComponent::CreateDescriptor(), AudioAreaEnvironmentComponent::CreateDescriptor(), AudioEnvironmentComponent::CreateDescriptor(), AudioListenerComponent::CreateDescriptor(), @@ -209,7 +203,6 @@ namespace LmbrCentral LmbrCentralAllocatorComponent::CreateDescriptor(), LmbrCentralAssetBuilderAllocatorComponent::CreateDescriptor(), LmbrCentralSystemComponent::CreateDescriptor(), - MeshComponent::CreateDescriptor(), NavigationComponent::CreateDescriptor(), SimpleStateComponent::CreateDescriptor(), SpawnerComponent::CreateDescriptor(), @@ -329,13 +322,6 @@ namespace LmbrCentral ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) ; } - - MaterialHandle::Reflect(serializeContext); - } - - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - MaterialHandle::Reflect(behaviorContext); } ReflectScriptableEvents::Reflect(context); @@ -379,10 +365,6 @@ namespace LmbrCentral // Register asset handlers. Requires "AssetDatabaseService" AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!"); - auto meshAssetHandler = aznew MeshAssetHandler(); - meshAssetHandler->Register(); // registers self with AssetManager - m_assetHandlers.emplace_back(meshAssetHandler); - // Add asset types and extensions to AssetCatalog. Uses "AssetCatalogService". auto assetCatalog = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); if (assetCatalog) @@ -518,8 +500,6 @@ namespace LmbrCentral gEnv = system.GetGlobalEnvironment(); #endif - REGISTER_INT(s_meshAssetHandler_AsyncCvar, 1, 0, "Enables asynchronous loading of legacy mesh formats"); - // Enable catalog now that application's asset root is set. if (system.GetGlobalEnvironment()->IsEditor()) { @@ -536,11 +516,6 @@ namespace LmbrCentral void LmbrCentralSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system) { - if (gEnv->pConsole) - { - gEnv->pConsole->UnregisterVariable(s_meshAssetHandler_AsyncCvar, true); - } - EBUS_EVENT(AZ::Data::AssetCatalogRequestBus, StopMonitoringAssets); #if !defined(AZ_MONOLITHIC_BUILD) diff --git a/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.cpp b/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.cpp index 14091a2e7a..8536733b01 100644 --- a/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.cpp +++ b/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.cpp @@ -16,7 +16,6 @@ #include "Ai/EditorNavigationAreaComponent.h" #include "Ai/EditorNavigationSeedComponent.h" -#include "Animation/EditorAttachmentComponent.h" #include "Audio/EditorAudioAreaEnvironmentComponent.h" #include "Audio/EditorAudioEnvironmentComponent.h" #include "Audio/EditorAudioListenerComponent.h" @@ -25,7 +24,6 @@ #include "Audio/EditorAudioRtpcComponent.h" #include "Audio/EditorAudioSwitchComponent.h" #include "Audio/EditorAudioTriggerComponent.h" -#include "Rendering/EditorMeshComponent.h" #include "Scripting/EditorLookAtComponent.h" #include "Scripting/EditorRandomTimedSpawnerComponent.h" #include "Scripting/EditorSpawnerComponent.h" @@ -61,7 +59,6 @@ namespace LmbrCentral : LmbrCentralModule() { m_descriptors.insert(m_descriptors.end(), { - EditorAttachmentComponent::CreateDescriptor(), EditorAudioAreaEnvironmentComponent::CreateDescriptor(), EditorAudioEnvironmentComponent::CreateDescriptor(), EditorAudioListenerComponent::CreateDescriptor(), @@ -70,7 +67,6 @@ namespace LmbrCentral EditorAudioRtpcComponent::CreateDescriptor(), EditorAudioSwitchComponent::CreateDescriptor(), EditorAudioTriggerComponent::CreateDescriptor(), - EditorMeshComponent::CreateDescriptor(), EditorTagComponent::CreateDescriptor(), EditorSphereShapeComponent::CreateDescriptor(), EditorDiskShapeComponent::CreateDescriptor(), @@ -107,8 +103,6 @@ namespace LmbrCentral typeIds.emplace_back(descriptor->GetUuid()); } EBUS_EVENT(AzFramework::MetricsPlainTextNameRegistrationBus, RegisterForNameSending, typeIds); - - EditorMeshBus::Handler::BusConnect(); } LmbrCentralEditorModule::~LmbrCentralEditorModule() @@ -123,11 +117,6 @@ namespace LmbrCentral return requiredComponents; } - - bool LmbrCentralEditorModule::AddMeshComponentWithAssetId(const AZ::EntityId& targetEntity, const AZ::Uuid& meshAssetId) - { - return AddMeshComponentWithMesh(targetEntity, meshAssetId); - } } // namespace LmbrCentral AZ_DECLARE_MODULE_CLASS(Gem_LmbrCentralEditor, LmbrCentral::LmbrCentralEditorModule) diff --git a/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.h b/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.h index f180c21d8d..7a9dbd01ba 100644 --- a/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.h +++ b/Gems/LmbrCentral/Code/Source/LmbrCentralEditor.h @@ -13,13 +13,6 @@ #include "LmbrCentral.h" -#include - -namespace Water -{ - class WaterVolumeConverter; -} - namespace LmbrCentral { /** @@ -31,7 +24,6 @@ namespace LmbrCentral */ class LmbrCentralEditorModule : public LmbrCentralModule - , public EditorMeshBus::Handler { public: AZ_RTTI(LmbrCentralEditorModule, "{1BF648D7-3703-4B52-A688-67C253A059F2}", LmbrCentralModule); @@ -39,7 +31,5 @@ namespace LmbrCentral LmbrCentralEditorModule(); ~LmbrCentralEditorModule(); AZ::ComponentTypeList GetRequiredSystemComponents() const override; - - bool AddMeshComponentWithAssetId(const AZ::EntityId& targetEntity, const AZ::Uuid& meshAssetId) override; }; } // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.cpp b/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.cpp deleted file mode 100644 index 64254ee8f0..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.cpp +++ /dev/null @@ -1,580 +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 "LmbrCentral_precompiled.h" - -#include "EditorMeshComponent.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include // For updating nav tiles on creation of editor physics. -#include // For basic physicalization at edit-time for object snapping. -#include -#include -#include - -#include -#include -#include - -namespace LmbrCentral -{ - AZ_CVAR(bool, cl_editorMeshIntersectionDebug, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Enable editor mesh intersection debugging"); - - void EditorMeshComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("Static Mesh Render Node", &EditorMeshComponent::m_mesh) - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("Mesh", "The Mesh component is the primary method of adding visual geometry to entities") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Rendering") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/StaticMesh.svg") - ->Attribute(AZ::Edit::Attributes::PrimaryAssetType, AZ::AzTypeInfo::Uuid()) - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/StaticMesh.png") - ->Attribute(AZ::Edit::Attributes::DynamicIconOverride, &EditorMeshComponent::GetMeshViewportIconPath) - ->Attribute(AZ::Edit::Attributes::PreferNoViewportIcon, true) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-static-mesh.html") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorMeshComponent::m_mesh) - ; - - editContext->Class( - "Render Options", "Rendering options for the mesh.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20)) - - ->ClassElement(AZ::Edit::ClassElements::Group, "Options") - ->Attribute(AZ::Edit::Attributes::AutoExpand, false) - - ->DataElement(AZ::Edit::UIHandlers::Slider, &MeshComponentRenderNode::MeshRenderOptions::m_opacity, "Opacity", "Opacity value") - ->Attribute(AZ::Edit::Attributes::Min, 0.f) - ->Attribute(AZ::Edit::Attributes::Max, 1.f) - ->Attribute(AZ::Edit::Attributes::Step, 0.1f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_maxViewDist, "Max view distance", "Maximum view distance in meters.") - ->Attribute(AZ::Edit::Attributes::Suffix, " m") - ->Attribute(AZ::Edit::Attributes::Min, 0.f) - ->Attribute(AZ::Edit::Attributes::Max, &MeshComponentRenderNode::GetDefaultMaxViewDist) - ->Attribute(AZ::Edit::Attributes::Step, 0.1f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_viewDistMultiplier, "View distance multiplier", "Adjusts max view distance. If 1.0 then default is used. 1.1 would be 10% further than default.") - ->Attribute(AZ::Edit::Attributes::Suffix, "x") - ->Attribute(AZ::Edit::Attributes::Min, 0.f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Slider, &MeshComponentRenderNode::MeshRenderOptions::m_lodRatio, "LOD distance ratio", "Controls LOD ratio over distance.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Min, 0) - ->Attribute(AZ::Edit::Attributes::Max, 255) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_castShadows, "Cast shadows", "Casts shadows.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_lodBoundingBoxBased, "LOD based on Bounding Boxes", "LOD based on Bounding Boxes.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_useVisAreas, "Use VisAreas", "Allow VisAreas to control this component's visibility.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - - ->ClassElement(AZ::Edit::ClassElements::Group, "Advanced") - ->Attribute(AZ::Edit::Attributes::AutoExpand, false) - - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_rainOccluder, "Rain occluder", "Occludes dynamic raindrops.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Visibility, &MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_affectDynamicWater, "Affect dynamic water", "Will generate ripples in dynamic water.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Visibility, &MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_receiveWind, "Receive wind", "Receives wind.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMajorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_acceptDecals, "Accept decals", "Can receive decals.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_affectNavmesh, "Affect navmesh", "Will affect navmesh generation.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Visibility, &MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_visibilityOccluder, "Visibility occluder", "Is appropriate for occluding visibility of other objects.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Visibility, &MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_dynamicMesh, "Deformable mesh", "Enables vertex deformation on mesh.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMajorChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::MeshRenderOptions::m_affectGI, "Affects GI", "Affects the global illumination results.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::MeshRenderOptions::OnMinorChanged) - ->Attribute(AZ::Edit::Attributes::Visibility, &MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility) - ; - - editContext->Class( - "Mesh Rendering", "Attach geometry to the entity.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Visibility, AZ_CRC("PropertyVisibility_ShowChildrenOnly", 0xef428f20)) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::m_visible, "Visible", "Is currently visible.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::RefreshRenderState) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::m_meshAsset, "Mesh asset", "Mesh asset reference") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::OnAssetPropertyChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::m_material, "Material override", "Optionally specify an override material.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::OnAssetPropertyChanged) - ->DataElement(AZ::Edit::UIHandlers::Default, &MeshComponentRenderNode::m_renderOptions, "Render options", "Render/draw options.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MeshComponentRenderNode::RefreshRenderState) - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->Class()->RequestBus("MeshComponentRequestBus"); - } - } - - void EditorMeshComponent::Activate() - { - EditorComponentBase::Activate(); - - m_mesh.AttachToEntity(m_entity->GetId()); - bool isStatic = false; - AZ::TransformBus::EventResult(isStatic, m_entity->GetId(), &AZ::TransformBus::Events::IsStaticTransform); - m_mesh.SetTransformStaticState(isStatic); - - bool visible = false; - AzToolsFramework::EditorEntityInfoRequestBus::EventResult( - visible, GetEntityId(), &AzToolsFramework::EditorEntityInfoRequestBus::Events::IsVisible); - m_mesh.UpdateAuxiliaryRenderFlags(!visible, ERF_HIDDEN); - - // Note we are purposely connecting to buses before calling m_mesh.CreateMesh(). - // m_mesh.CreateMesh() can result in events (eg: OnMeshCreated) that we want receive. - MaterialOwnerRequestBus::Handler::BusConnect(m_entity->GetId()); - AzFramework::BoundsRequestBus::Handler::BusConnect(m_entity->GetId()); - MeshComponentRequestBus::Handler::BusConnect(m_entity->GetId()); - MeshComponentNotificationBus::Handler::BusConnect(m_entity->GetId()); - LegacyMeshComponentRequestBus::Handler::BusConnect(m_entity->GetId()); - RenderNodeRequestBus::Handler::BusConnect(m_entity->GetId()); - AZ::TransformNotificationBus::Handler::BusConnect(m_entity->GetId()); - AzToolsFramework::EditorVisibilityNotificationBus::Handler::BusConnect(GetEntityId()); - AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId()); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(GetEntityId()); - AzToolsFramework::EditorComponentSelectionNotificationsBus::Handler::BusConnect(GetEntityId()); - AzFramework::AssetCatalogEventBus::Handler::BusConnect(); - AzFramework::EntityIdContextQueryBus::EventResult(m_contextId, GetEntityId(), &AzFramework::EntityIdContextQueries::GetOwningContextId); - AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusConnect({ GetEntityId(), m_contextId }); - - m_mesh.m_renderOptions.m_changeCallback = - [this]() - { - m_mesh.RefreshRenderState(); - AffectNavmesh(); - }; - - m_mesh.CreateMesh(); - } - - void EditorMeshComponent::Deactivate() - { - AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); - AZ::Data::AssetBus::Handler::BusDisconnect(); - MaterialOwnerRequestBus::Handler::BusDisconnect(); - AzFramework::BoundsRequestBus::Handler::BusDisconnect(); - MeshComponentRequestBus::Handler::BusDisconnect(); - MeshComponentNotificationBus::Handler::BusDisconnect(); - LegacyMeshComponentRequestBus::Handler::BusDisconnect(); - RenderNodeRequestBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::EditorVisibilityNotificationBus::Handler::BusDisconnect(); - AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusDisconnect(); - AzToolsFramework::EditorComponentSelectionNotificationsBus::Handler::BusDisconnect(); - - AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusDisconnect(); - - m_mesh.m_renderOptions.m_changeCallback = nullptr; - - m_mesh.DestroyMesh(); - m_mesh.AttachToEntity(AZ::EntityId()); - - EditorComponentBase::Deactivate(); - } - - - void EditorMeshComponent::OnMeshCreated(const AZ::Data::Asset& asset) - { - AZ::Data::AssetBus::Handler::BusDisconnect(); - AZ::Data::AssetBus::Handler::BusConnect(asset.GetId()); - - using namespace AzFramework::RenderGeometry; - IntersectionNotificationBus::Event(m_contextId, &IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - void EditorMeshComponent::OnMeshDestroyed() - { - using namespace AzFramework::RenderGeometry; - IntersectionNotificationBus::Event(m_contextId, &IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - IRenderNode* EditorMeshComponent::GetRenderNode() - { - return &m_mesh; - } - - float EditorMeshComponent::GetRenderNodeRequestBusOrder() const - { - return s_renderNodeRequestBusOrder; - } - - void EditorMeshComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) - { - AZ_UNUSED(world); - - using namespace AzFramework::RenderGeometry; - IntersectionNotificationBus::Event(m_contextId, &IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - void EditorMeshComponent::OnStaticChanged(bool isStatic) - { - m_mesh.SetTransformStaticState(isStatic); - if (m_mesh.m_renderOptions.m_changeCallback) - { - m_mesh.m_renderOptions.m_changeCallback(); - } - AffectNavmesh(); - } - - AZ::Aabb EditorMeshComponent::GetWorldBounds() - { - return m_mesh.CalculateWorldAABB(); - } - - AZ::Aabb EditorMeshComponent::GetLocalBounds() - { - return m_mesh.CalculateLocalAABB(); - } - - AzFramework::RenderGeometry::RayResult EditorMeshComponent::RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) - { - AzFramework::RenderGeometry::RayResult result; - if (!GetVisibility() && ray.m_onlyVisible) - { - return result; - } - - if (IStatObj* geometry = GetStatObj()) - { - const AZ::Vector3 rayDirection = (ray.m_endWorldPosition - ray.m_startWorldPosition); - const AZ::Transform& transform = GetTransform()->GetWorldTM(); - const AZ::Transform inverseTransform = transform.GetInverse(); - - const AZ::Vector3 rayStartLocal = inverseTransform.TransformPoint(ray.m_startWorldPosition); - const AZ::Vector3 rayDistNormLocal = inverseTransform.TransformVector(rayDirection).GetNormalized(); - - SRayHitInfo hi; - hi.inReferencePoint = AZVec3ToLYVec3(rayStartLocal); - hi.inRay = Ray(hi.inReferencePoint, AZVec3ToLYVec3(rayDistNormLocal)); - hi.bInFirstHit = true; - hi.bGetVertColorAndTC = true; - - if (geometry->RayIntersection(hi)) - { - AZ::Matrix3x4 invTransformMatrix = AZ::Matrix3x4::CreateFromTransform(inverseTransform); - invTransformMatrix.Transpose(); - - result.m_uv = LYVec2ToAZVec2(hi.vHitTC); - result.m_worldPosition = transform.TransformPoint(LYVec3ToAZVec3(hi.vHitPos)); - result.m_worldNormal = invTransformMatrix.Multiply3x3(LYVec3ToAZVec3(hi.vHitNormal)).GetNormalized(); - result.m_distance = (result.m_worldPosition - ray.m_startWorldPosition).GetLength(); - result.m_entityAndComponent = { GetEntityId(), GetId() }; - if (cl_editorMeshIntersectionDebug) - { - m_debugPos = result.m_worldPosition; - m_debugNormal = result.m_worldNormal; - } - } - } - - return result; - } - - void EditorMeshComponent::SetMeshAsset(const AZ::Data::AssetId& id) - { - m_mesh.SetMeshAsset(id); - AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, - GetEntityId()); - } - - void EditorMeshComponent::SetMaterial(_smart_ptr material) - { - m_mesh.SetMaterial(material); - - AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, - AzToolsFramework::Refresh_AttributesAndValues); - } - - _smart_ptr EditorMeshComponent::GetMaterial() - { - return m_mesh.GetMaterial(); - } - - void EditorMeshComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId) - { - SetMeshAsset(assetId); - } - - void EditorMeshComponent::OnEntityVisibilityChanged(bool visibility) - { - m_mesh.UpdateAuxiliaryRenderFlags(!visibility, ERF_HIDDEN); - m_mesh.RefreshRenderState(); - } - - static void DecideColor( - const bool selected, const bool mouseHovered, const bool visible, - ColorB& triangleColor, ColorB& lineColor) - { - const ColorB translucentPurple = ColorB(250, 0, 250, 30); - - // default both colors to hidden - triangleColor = ColorB(AZ::u32(0)); - lineColor = ColorB(AZ::u32(0)); - - if (selected) - { - if (!visible) - { - lineColor = Col_Black; - - if (mouseHovered) - { - triangleColor = translucentPurple; - } - } - } - else - { - if (mouseHovered) - { - triangleColor = translucentPurple; - lineColor = AZColorToLYColorF(AzFramework::ViewportColors::HoverColor); - } - } - } - - void EditorMeshComponent::DisplayEntityViewport( - [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) - { - const bool mouseHovered = m_accentType == AzToolsFramework::EntityAccentType::Hover; - - IEditor* editor = nullptr; - AzToolsFramework::EditorRequests::Bus::BroadcastResult(editor, &AzToolsFramework::EditorRequests::GetEditor); - - const bool highlightGeometryOnMouseHover = editor->GetEditorSettings()->viewports.bHighlightMouseOverGeometry; - // if the mesh component is not visible, when selected we still draw the wireframe to indicate the shapes extent and position - const bool highlightGeometryWhenSelected = editor->GetEditorSettings()->viewports.bHighlightSelectedGeometry || !GetVisibility(); - - if ((!IsSelected() && mouseHovered && highlightGeometryOnMouseHover) || (IsSelected() && highlightGeometryWhenSelected)) - { - AZ::Transform transform = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); - - ColorB triangleColor, lineColor; - DecideColor(IsSelected(), mouseHovered, GetVisibility(), triangleColor, lineColor); - - SGeometryDebugDrawInfo dd; - dd.tm = AZTransformToLYTransform(transform); - dd.bExtrude = true; - dd.color = triangleColor; - dd.lineColor = lineColor; - - if (IStatObj* geometry = GetStatObj()) - { - geometry->DebugDraw(dd); - } - } - - if (cl_editorMeshIntersectionDebug) - { - debugDisplay.DrawArrow(m_debugPos, m_debugPos + (0.1f * m_debugNormal), 0.1f); - debugDisplay.DrawBall(m_debugPos, 0.03f); - debugDisplay.DrawWireBox(GetWorldBounds().GetMin(), GetWorldBounds().GetMax()); - } - } - - void EditorMeshComponent::BuildGameEntity(AZ::Entity* gameEntity) - { - if (auto meshComponent = gameEntity->CreateComponent()) - { - m_mesh.CopyPropertiesTo(meshComponent->m_meshRenderNode); - // ensure we do not copy across the edit time entity id - meshComponent->m_meshRenderNode.m_renderOptions.m_attachedToEntityId = AZ::EntityId(); - } - } - - - IStatObj* EditorMeshComponent::GetStatObj() - { - return m_mesh.GetEntityStatObj(); - } - - bool EditorMeshComponent::GetVisibility() - { - return m_mesh.GetVisible(); - } - - void EditorMeshComponent::SetVisibility(bool visible) - { - m_mesh.SetVisible(visible); - } - - void EditorMeshComponent::AffectNavmesh() - { - // Refresh the nav tile when the flag changes. - INavigationSystem* pNavigationSystem = nullptr; // INavigationSystem will be converted to an AZInterface (LY-111343) - if (pNavigationSystem) - { - pNavigationSystem->WorldChanged(AZAabbToLyAABB(GetWorldBounds())); - } - } - - AZStd::string_view staticViewportIcon = "Icons/Components/Viewport/StaticMesh.png"; - AZStd::string_view dynamicViewportIcon = "Icons/Components/Viewport/DynamicMesh.png"; - AZStd::string EditorMeshComponent::GetMeshViewportIconPath() const - { - if (m_mesh.m_renderOptions.IsStatic()) - { - return staticViewportIcon; - } - - return dynamicViewportIcon; - } - - void EditorMeshComponent::OnAssetReloaded(AZ::Data::Asset /*asset*/) - { - using namespace AzFramework::RenderGeometry; - IntersectionNotificationBus::Event(m_contextId, &IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - void EditorMeshComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& /*assetInfo*/) - { - if (m_mesh.m_meshAsset.GetId() != assetId) - { - return; - } - // If this editor mesh component is loaded and active in the level, it's referencing an asset that was just removed. - // Clearing this asset reference will help visualize this change. Note that this won't clear all references to this - // asset automatically, any levels that aren't loaded won't have the reference removed. - - // Set the mesh asset to invalid on the main thread. - AZ::TickBus::QueueFunction([this, assetId]() - { - // Emit a warning so users know this has occurred, it may not be intentional because the asset was removed before - // the references were cleared. Do this on the main thread. - AZ_Warning("EditorMeshComponent", false, "asset with ID %s referenced by entity named '%s' with ID %s was removed, this reference will be cleared on the associated component.", - assetId.ToString().c_str(), - GetEntity() ? GetEntity()->GetName().c_str() : "Invalid entity", - GetEntityId().ToString().c_str()); - - m_mesh.DestroyMesh(); - AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationRequests::AddDirtyEntity, - GetEntityId()); - AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast( - &AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, - AzToolsFramework::Refresh_AttributesAndValues); - }); - } - - AZ::Aabb EditorMeshComponent::GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/) - { - return GetWorldBounds(); - } - - bool EditorMeshComponent::EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/, - const AZ::Vector3& src, const AZ::Vector3& dir, float& distance) - { - if (IStatObj* geometry = GetStatObj()) - { - AZ::Transform transform = AZ::Transform::CreateIdentity(); - AZ::TransformBus::EventResult(transform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); - auto legacyTransform = AZTransformToLYTransform(transform); - const auto legacySrc = AZVec3ToLYVec3(src); - const auto legacyDir = AZVec3ToLYVec3(dir); - - const Matrix34 inverseTM = legacyTransform.GetInverted(); - const Vec3 raySrcLocal = inverseTM.TransformPoint(legacySrc); - const Vec3 rayDirLocal = inverseTM.TransformVector(legacyDir).GetNormalized(); - - SRayHitInfo hi; - hi.inReferencePoint = raySrcLocal; - hi.inRay = Ray(raySrcLocal, rayDirLocal); - if (geometry->RayIntersection(hi)) - { - const Vec3 worldHitPos = legacyTransform.TransformPoint(hi.vHitPos); - distance = legacySrc.GetDistance(worldHitPos); - return true; - } - } - - return false; - } - - void EditorMeshComponent::OnAccentTypeChanged(AzToolsFramework::EntityAccentType accent) - { - m_accentType = accent; - } - - bool AddMeshComponentWithMesh(const AZ::EntityId& targetEntity, const AZ::Uuid& meshAssetId) - { - // Error handling for failures should be done at the call site, this function can be invoked from Python. - if (!targetEntity.IsValid()) - { - return false; - } - AZ::ComponentTypeList componentsToAdd; - componentsToAdd.push_back(AZ::AzTypeInfo::Uuid()); - - AZStd::vector entityList; - entityList.push_back(targetEntity); - - AzToolsFramework::EntityCompositionRequests::AddComponentsOutcome outcome = - AZ::Failure(AZStd::string("Failed to call AddComponentsToEntities on EntityCompositionRequestBus")); - AzToolsFramework::EntityCompositionRequestBus::BroadcastResult(outcome, &AzToolsFramework::EntityCompositionRequests::AddComponentsToEntities, entityList, componentsToAdd); - - if (!outcome.IsSuccess()) - { - return false; - } - - AZ::Data::AssetId meshAsset(meshAssetId); - - // If necessary, the call site can verify if the mesh was actually set. - LmbrCentral::MeshComponentRequestBus::Event( - targetEntity, - &LmbrCentral::MeshComponentRequestBus::Events::SetMeshAsset, - meshAsset); - return true; - } -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.h b/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.h deleted file mode 100644 index 7617673e3b..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/EditorMeshComponent.h +++ /dev/null @@ -1,175 +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 -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include "MeshComponent.h" - - -struct IPhysicalEntity; - -namespace LmbrCentral -{ - /** - * In-editor mesh component. - * Conducts some additional listening and operations to ensure immediate - * effects when changing fields in the editor. - */ - class EditorMeshComponent - : public AzToolsFramework::Components::EditorComponentBase - , public AZ::Data::AssetBus::Handler - , private AzFramework::AssetCatalogEventBus::Handler - , public AzFramework::BoundsRequestBus::Handler - , private AzFramework::RenderGeometry::IntersectionRequestBus::Handler - , private MeshComponentRequestBus::Handler - , private MaterialOwnerRequestBus::Handler - , private MeshComponentNotificationBus::Handler - , private RenderNodeRequestBus::Handler - , private AZ::TransformNotificationBus::Handler - , private AzToolsFramework::EntitySelectionEvents::Bus::Handler - , private AzToolsFramework::EditorVisibilityNotificationBus::Handler - , private AzFramework::EntityDebugDisplayEventBus::Handler - , private LegacyMeshComponentRequestBus::Handler - , private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler - , private AzToolsFramework::EditorComponentSelectionNotificationsBus::Handler - { - public: - AZ_COMPONENT(EditorMeshComponent, "{FC315B86-3280-4D03-B4F0-5553D7D08432}", AzToolsFramework::Components::EditorComponentBase) - - ~EditorMeshComponent() = default; - - const float s_renderNodeRequestBusOrder = 100.f; - - // AZ::Component overrides ... - void Activate() override; - void Deactivate() override; - - // BoundsRequestBus and MeshComponentRequestBus overrides ... - AZ::Aabb GetWorldBounds() override; - AZ::Aabb GetLocalBounds() override; - - // IntersectionRequestBus overrides ... - AzFramework::RenderGeometry::RayResult RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) override; - - // MeshComponentRequestBus overrides ... - void SetMeshAsset(const AZ::Data::AssetId& id) override; - AZ::Data::Asset GetMeshAsset() override { return m_mesh.GetMeshAsset(); } - void SetVisibility(bool visible) override; - bool GetVisibility() override; - - // MaterialOwnerRequestBus overrides ... - void SetMaterial(_smart_ptr) override; - _smart_ptr GetMaterial() override; - - // MeshComponentNotificationBus overrides ... - void OnMeshCreated(const AZ::Data::Asset& asset) override; - void OnMeshDestroyed() override; - - // RenderNodeRequestBus overrides ... - IRenderNode* GetRenderNode() override; - float GetRenderNodeRequestBusOrder() const override; - - // TransformNotificationBus overrides ... - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - void OnStaticChanged(bool isStatic) override; - - // EditorVisibilityNotificationBus overrides ... - void OnEntityVisibilityChanged(bool visibility) override; - - // AzFramework::EntityDebugDisplayEventBus overrides .... - void DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; - - //! Called when you want to change the game asset through code (like when creating components based on assets). - void SetPrimaryAsset(const AZ::Data::AssetId& assetId) override; - - // LegacyMeshComponentRequests overrides ... - IStatObj* GetStatObj() override; - - // EditorComponentBase overrides ... - void BuildGameEntity(AZ::Entity* gameEntity) override; - - // AZ::Data::AssetBus overrides ... - void OnAssetReloaded(AZ::Data::Asset asset) override; - - // AzFramework::AssetCatalogEventBus overrides ... - void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override; - - // EditorComponentSelectionRequestsBus overrides ... - AZ::Aabb GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& viewportInfo) override; - bool EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& viewportInfo, - const AZ::Vector3& src, const AZ::Vector3& dir, float& distance) override; - bool SupportsEditorRayIntersect() override { return true; } - - // EditorComponentSelectionNotificationsBus overrides ... - void OnAccentTypeChanged(AzToolsFramework::EntityAccentType accent) override; - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("MeshService", 0x71d8a455)); - provided.push_back(AZ_CRC("LegacyMeshService", 0xb462a299)); - } - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - dependent.push_back(AZ_CRC("EditorVisibilityService", 0x90888caf)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("MeshService", 0x71d8a455)); - incompatible.push_back(AZ_CRC("LegacyMeshService", 0xb462a299)); - } - - static void Reflect(AZ::ReflectContext* context); - - protected: - - // Decides if this mesh affects the navmesh or not. - void AffectNavmesh(); - - AZStd::string GetMeshViewportIconPath() const; - - AzToolsFramework::EntityAccentType m_accentType = AzToolsFramework::EntityAccentType::None; ///< State of the entity selection in the viewport. - MeshComponentRenderNode m_mesh; ///< IRender node implementation. - - AzFramework::EntityContextId m_contextId; - AZ::Vector3 m_debugPos = AZ::Vector3(0); - AZ::Vector3 m_debugNormal = AZ::Vector3(0); - }; - - // Helper function useful for automation. - bool AddMeshComponentWithMesh(const AZ::EntityId& targetEntity, const AZ::Uuid& meshAssetId); -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/MaterialHandle.cpp b/Gems/LmbrCentral/Code/Source/Rendering/MaterialHandle.cpp deleted file mode 100644 index 6171951398..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/MaterialHandle.cpp +++ /dev/null @@ -1,399 +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 "LmbrCentral_precompiled.h" -#include -#include -#include -#include -#include -#include -#include - - -namespace LmbrCentral -{ - // Provides a set of reflected functions for operating on IMaterial through a MaterialHandle - // We keep these cpp-private instead of putting them in the header to align with the fact that - // MaterialHandle is not useful on the code side, and only exists to support reflection. If it - // were possible to reflect IMaterial directly, we'd still have this same set of functions here. - namespace MaterialHandleFunctions - { - void SetParamVector4(MaterialHandle* thisPtr, const AZStd::string& name, const AZ::Vector4& value) - { - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - Vec4 vec4(value.GetX(), value.GetY(), value.GetZ(), value.GetW()); - thisPtr->m_material->SetGetMaterialParamVec4(name.c_str(), vec4, false, true); - } - else - { - AZ_Error("Material", false, "SetParamVector4 only accepts single Materials, not Material Groups"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to SetParamVector4"); - } - } - - void SetParamVector3(MaterialHandle* thisPtr, const AZStd::string& name, const AZ::Vector3& value) - { - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - Vec3 vec3(value.GetX(), value.GetY(), value.GetZ()); - thisPtr->m_material->SetGetMaterialParamVec3(name.c_str(), vec3, false, true); - } - else - { - AZ_Error("Material", false, "SetParamVector3 only accepts single Materials, not Material Groups"); - } - - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to SetParamVector3"); - } - } - - void SetParamColor(MaterialHandle* thisPtr, const AZStd::string& name, const AZ::Color& value) - { - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - // When value had garbage data is was not only making the material render black, it also corrupted something - // on the GPU, making black boxes flicker over the sky. - // It was garbage due to a bug in the Color object node where all fields have to be set to some value manually; the default is not 0. - if ((value.GetR() < 0 || value.GetR() > 1) || - (value.GetG() < 0 || value.GetG() > 1) || - (value.GetB() < 0 || value.GetB() > 1) || - (value.GetA() < 0 || value.GetA() > 1)) - { - return; - } - - Vec4 vec4(value.GetR(), value.GetG(), value.GetB(), value.GetA()); - thisPtr->m_material->SetGetMaterialParamVec4(name.c_str(), vec4, false, true); - } - else - { - AZ_Error("Material", false, "SetParamColor only accepts single Materials, not Material Groups"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to SetParamColor"); - } - } - - void SetParamFloat(MaterialHandle* thisPtr, const AZStd::string& name, float value) - { - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - thisPtr->m_material->SetGetMaterialParamFloat(name.c_str(), value, false, true); - } - else - { - AZ_Error("Material", false, "SetParamFloat only accepts single Materials, not Material Groups"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to SetParamFloat"); - } - } - - AZ::Vector4 GetParamVector4(MaterialHandle* thisPtr, const AZStd::string& name) - { - AZ::Vector4 value = AZ::Vector4::CreateZero(); - - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - Vec4 vec4; - if (thisPtr->m_material->SetGetMaterialParamVec4(name.c_str(), vec4, true, true)) - { - value.Set(vec4.x, vec4.y, vec4.z, vec4.w); - } - } - else - { - AZ_Error("Material", false, "GetParamVector4 only accepts single Materials, not Material Groups"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to GetParamVector4"); - } - - return value; - } - - AZ::Vector3 GetParamVector3(MaterialHandle* thisPtr, const AZStd::string& name) - { - AZ::Vector3 value = AZ::Vector3::CreateZero(); - - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - Vec3 vec3; - if (thisPtr->m_material->SetGetMaterialParamVec3(name.c_str(), vec3, true, true)) - { - value.Set(vec3.x, vec3.y, vec3.z); - } - } - else - { - AZ_Error("Material", false, "GetParamVector3 only accepts single Materials, not Material Groups"); - } - - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to GetParamVector3"); - } - - return value; - } - - AZ::Color GetParamColor(MaterialHandle* thisPtr, const AZStd::string& name) - { - AZ::Color value = AZ::Color::CreateZero(); - - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - Vec4 vec4; - if (thisPtr->m_material->SetGetMaterialParamVec4(name.c_str(), vec4, true, true)) - { - value.Set(vec4.x, vec4.y, vec4.z, vec4.w); - } - } - else - { - AZ_Error("Material", false, "GetParamColor only accepts single Materials, not Material Groups"); - } - - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to GetParamColor"); - } - - return value; - } - - float GetParamFloat(MaterialHandle* thisPtr, const AZStd::string& name) - { - float value = 0.0f; - - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsMaterialGroup()) - { - thisPtr->m_material->SetGetMaterialParamFloat(name.c_str(), value, true, true); - } - else - { - AZ_Error("Material", false, "GetParamFloat only accepts single Materials, not Material Groups"); - } - - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to GetParamFloat"); - } - - return value; - } - - MaterialHandle Clone(MaterialHandle* thisPtr) - { - MaterialHandle copy; - - if (thisPtr && thisPtr->m_material) - { - if (!thisPtr->m_material->IsSubMaterial()) - { - copy.m_material = gEnv->p3DEngine->GetMaterialManager()->CloneMultiMaterial(thisPtr->m_material); - } - else - { - AZ_Error("Material", false, "Clone does not support Sub-Materials"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to Clone"); - } - - return copy; - } - - MaterialHandle FindByName(const AZStd::string& name) - { - MaterialHandle found; - found.m_material = gEnv->p3DEngine->GetMaterialManager()->FindMaterial(name.c_str()); - return found; - } - - MaterialHandle LoadByName(const AZStd::string& name) - { - LmbrCentral::MaterialHandle handle; - handle.m_material = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(name.c_str(), false, false, IMaterialManager::ELoadingFlagsPreviewMode); - - AZ_Error(nullptr, handle.m_material, "Material.LoadByName('%s') failed", name.c_str()); - - return handle; - } - - _smart_ptr GetSubMaterialHelper(_smart_ptr materialGroup, int materialId) - { - if (materialGroup) - { - if (materialGroup->IsMaterialGroup()) - { - int subMtlCount = materialGroup->GetSubMtlCount(); - if (materialId >= 1 && materialId <= subMtlCount) - { - return materialGroup->GetSubMtl(materialId-1); - } - else - { - AZ_Error("Material", false, "Invalid Material ID %d passed to FindSubMaterial. %d Materials are available.", materialId, subMtlCount); - } - } - else - { - AZ_Error("Material", false, "FindSubMaterial does not support single Material"); - } - } - else - { - AZ_Warning("Material", false, "Invalid Material passed to FindSubMaterial."); - } - - return nullptr; - } - - - - MaterialHandle FindSubMaterial(const AZStd::string& name, int id, bool shouldLoad) - { - MaterialHandle found; - _smart_ptr materialGroup = gEnv->p3DEngine->GetMaterialManager()->FindMaterial(name.c_str()); - if (materialGroup) - { - found.m_material = GetSubMaterialHelper(materialGroup, id); - } - else - { - if (shouldLoad) - { - materialGroup = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(name.c_str(), false, false, IMaterialManager::ELoadingFlagsPreviewMode); - if (materialGroup) - { - found.m_material = GetSubMaterialHelper(materialGroup, id); - } - else - { - AZ_Error("Material", false, "Load Material '%s' failed", name.c_str()); - } - } - else - { - AZ_Warning("Material", false, "No Sub-Material is found since Material '%s' is not loaded", name.c_str()); - } - } - - return found; - } - - AZStd::string ToString(MaterialHandle* thisPtr) - { - if (!thisPtr || !thisPtr->m_material) - { - return "Invalid"; - } - else - { - return thisPtr->m_material->GetName(); - } - } - } - - void MaterialHandle::Reflect(AZ::SerializeContext* serializeContext) - { - // This is required in order to create a MaterialHandle variable in script canvas. - serializeContext->Class()->Version(0); - } - - void MaterialHandle::Reflect(AZ::BehaviorContext* behaviorContext) - { - const char* setMaterialParamTooltip = "Sets a Material param value"; - const char* getMaterialParamTooltip = "Returns a Material param value"; - AZ::BehaviorParameterOverrides setMaterialDetails = { "Material", "The Material to modify" }; - AZ::BehaviorParameterOverrides getMaterialDetails = { "Material", "The Material to inspect" }; - AZ::BehaviorParameterOverrides setParamNameDetails = { "ParamName", "The name of the Material param to set" }; - AZ::BehaviorParameterOverrides getParamNameDetails = { "ParamName", "The name of the Material param to return" }; - const AZStd::array getMaterialParamArgs = { { getMaterialDetails,getParamNameDetails } }; - const char* newValueTooltip = "The new value to apply"; - - behaviorContext->Class("Material") - ->Attribute(AZ::Script::Attributes::Category, "Rendering") - ->Method("ToString", &MaterialHandleFunctions::ToString) - ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) // Hide this node because it doesn't really make sense for the user (GetName would be better), but we need "ToString" in order to provide nice output in Material Variable nodes in script canvas. - ->Method("FindByName", &MaterialHandleFunctions::FindByName, { { { "Name", "Full path name of the Material" } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, "Find a Material by name. Returns Invalid if the Material is not already loaded.") - ->Method("LoadByName", &MaterialHandleFunctions::LoadByName, { { { "Name", "Full path name of the Material" } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, "Find a Material by name, loading the asset if needed. Returns Invalid if the Material could not be found or loaded.") - ->Method("Clone", &MaterialHandleFunctions::Clone, { { { "Material", "The Material to clone" } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, "Creates a copy of the given Material.") - ->Method("FindSubMaterial", &MaterialHandleFunctions::FindSubMaterial, - { { { "Name", "Full path name of the Material Group to get a Sub-Material from" }, - { "MaterialID", "The ID of a Sub-Material to access. IDs start at 1.", behaviorContext->MakeDefaultValue(1) }, - { "ShouldLoad", "Whether to load the Material Group or not if it's not loaded", behaviorContext->MakeDefaultValue(true) } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, "Find a Sub-Material from a Material Group by specified Material ID. Returns Invalid if the Material Group could not be found or loaded or the Sub-Material could not be found.") - ->Method("SetParamVector4", &MaterialHandleFunctions::SetParamVector4, - { { setMaterialDetails,setParamNameDetails,{ "Vector4", newValueTooltip } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Method("SetParamVector3", &MaterialHandleFunctions::SetParamVector3, - { { setMaterialDetails,setParamNameDetails,{ "Vector3", newValueTooltip } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Method("SetParamColor", &MaterialHandleFunctions::SetParamColor, - { { setMaterialDetails,setParamNameDetails,{ "Color", newValueTooltip } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Method("SetParamNumber", &MaterialHandleFunctions::SetParamFloat, // Using "ParamNumber" instead of "ParamFloat" because in Script Canvas all primitives are just "numbers" - { { setMaterialDetails,setParamNameDetails,{ "Number", newValueTooltip } } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Method("GetParamVector4", &MaterialHandleFunctions::GetParamVector4, getMaterialParamArgs) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Method("GetParamVector3", &MaterialHandleFunctions::GetParamVector3, getMaterialParamArgs) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Method("GetParamColor", &MaterialHandleFunctions::GetParamColor, getMaterialParamArgs) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Method("GetParamNumber", &MaterialHandleFunctions::GetParamFloat, getMaterialParamArgs) // Using "ParamNumber" instead of "ParamFloat" because in Script Canvas all primitives are just "numbers" - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ; - } -} diff --git a/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.cpp b/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.cpp deleted file mode 100644 index 18b9003e4f..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.cpp +++ /dev/null @@ -1,265 +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 "LmbrCentral_precompiled.h" - -#include -#include -#include -#include -#include -#include - -#include -#include "MeshAssetHandler.h" - -#include -#include - -namespace LmbrCentral -{ - ////////////////////////////////////////////////////////////////////////// - const AZStd::string MeshAssetHandlerHelper::s_assetAliasToken = "@assets@/"; - - // what mesh do we use as a placeholder when its currently busy compiling? - static const char* g_meshCompilingSubstituteAsset = "engineassets/objects/default.cgf"; - - MeshAssetHandlerHelper::MeshAssetHandlerHelper() - : m_asyncLoadCvar(nullptr) - { - } - - void MeshAssetHandlerHelper::StripAssetAlias(const char*& assetPath) - { - const size_t assetAliasTokenLen = s_assetAliasToken.size() - 1; - if (0 == strncmp(assetPath, s_assetAliasToken.c_str(), assetAliasTokenLen)) - { - assetPath += assetAliasTokenLen; - } - } - - ICVar* MeshAssetHandlerHelper::GetAsyncLoadCVar() - { - if (!m_asyncLoadCvar) - { - m_asyncLoadCvar = gEnv->pConsole->GetCVar(s_meshAssetHandler_AsyncCvar); - } - - return m_asyncLoadCvar; - } - - ////////////////////////////////////////////////////////////////////////// - // Static Mesh Asset Handler - ////////////////////////////////////////////////////////////////////////// - - void AsyncStatObjLoadCallback(const AZ::Data::Asset& asset, _smart_ptr statObj) - { - if (statObj) - { - asset.Get()->m_statObj = statObj; - } - else - { -#if defined(AZ_ENABLE_TRACING) - AZStd::string assetDescription = asset.ToString(); - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetDescription, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, asset.GetId()); - AZ_Error("MeshAssetHandler", false, "Failed to load mesh asset %s", assetDescription.c_str()); -#endif // AZ_ENABLE_TRACING - } - } - - MeshAssetHandler::~MeshAssetHandler() - { - Unregister(); - } - - AZ::Data::AssetPtr MeshAssetHandler::CreateAsset([[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) - { - (void)type; - - AZ_Assert(type == AZ::AzTypeInfo::Uuid(), "Invalid asset type! We handle only 'MeshAsset'"); - - return aznew MeshAsset(); - } - - AZ::Data::AssetId MeshAssetHandler::AssetMissingInCatalog([[maybe_unused]] const AZ::Data::Asset& asset) - { - // if tracing is disabled, we are likely in a situation where we specifically don't want any diagnostic information or "errors" to appear - // so in that case, don't load anything, don't substitute anything, don't escalate anything, just let the empty blank asset return. -#if defined(AZ_ENABLE_TRACING) - if (asset.GetId().IsValid()) - { - // find out whether its still compiling or it will never be available because its source file is missing. - // this also escalates it, if found, to the top of the build queue: - AzFramework::AssetSystem::AssetStatus statusResult = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult(statusResult, &AzFramework::AssetSystem::AssetSystemRequests::GetAssetStatusById, asset.GetId()); - - if ((statusResult == AzFramework::AssetSystem::AssetStatus_Compiling) || (statusResult == AzFramework::AssetSystem::AssetStatus_Queued)) - { - // note that we can also check other codes and substitute other meshes if we want, here... - // its currently compiling and will finish soon. - // substitute a placeholder mesh: - - if (!m_missingMeshAssetId.IsValid()) - { - // substitute the missing mesh assetId so that there's at least something to render that indicates a problem - // in builds where there is no diagnostics or tracing, don't substitute anything, to prefer that there's no visual indication that - // something is wrong in shipped games. - AZ::Data::AssetCatalogRequestBus::BroadcastResult(m_missingMeshAssetId, &AZ::Data::AssetCatalogRequests::GetAssetIdByPath, g_meshCompilingSubstituteAsset, azrtti_typeid(), false); - AZ_Error("Mesh Asset Handler", m_missingMeshAssetId.IsValid(), "Attempted to substitute %s for a missing asset, but it is also missing!", g_meshCompilingSubstituteAsset); - } - - if (m_missingMeshAssetId.IsValid()) - { - AZ_TracePrintf("MeshAssetHandler", " - substituting with default asset ID %s\n", m_missingMeshAssetId.ToString().c_str()); - // substitute the missing mesh asset. - return m_missingMeshAssetId; - } - } - } -#endif // defined(AZ_ENABLE_TRACING) - - // otherwise, if we get here, it means that either it was truly missing, in which case let an error occur, or the missing default substitute asset - // is also itself missing! - return AZ::Data::AssetId(); - } - - - - void MeshAssetHandler::GetCustomAssetStreamInfoForLoad(AZ::Data::AssetStreamInfo& streamInfo) - { - // The StatObj system only takes in a file name for loading, not a memory buffer. - // If we set our stream data length to 0, the asset system will skip any file I/O for reading the data, and will instead - // go directly into the AssetHandler for processing. - streamInfo.m_dataLen = 0; - } - - AZ::Data::AssetHandler::LoadResult MeshAssetHandler::LoadAssetData( - const AZ::Data::Asset& asset, - AZStd::shared_ptr stream, - const AZ::Data::AssetFilterCB& /*assetLoadFilterCB*/) - { - const char* assetPath = stream->GetFilename(); - - AZ_Assert(asset.GetType() == AZ::AzTypeInfo::Uuid(), "Invalid asset type! We only load 'MeshAsset'"); - if (MeshAsset* meshAsset = asset.GetAs()) - { - AZ_Assert(!meshAsset->m_statObj.get(), "Attempting to create static mesh without cleaning up the old one."); - - // Strip the alias. StatObj instances are stored in a dictionary by their path, - // so to share instances with legacy cry entities, we need to use the same un-aliased format. - StripAssetAlias(assetPath); - - // Temporary cvar guard while async loading of legacy mesh formats is stabilized. - ICVar* cvar = GetAsyncLoadCVar(); - if (!cvar || cvar->GetIVal() == 0) - { - if (gEnv->mMainThreadId != CryGetCurrentThreadId()) - { - AZStd::binary_semaphore signaller; - - auto callback = [&asset, &signaller](IStatObj* obj) - { - AsyncStatObjLoadCallback(asset, obj); - signaller.release(); - }; - - gEnv->p3DEngine->LoadStatObjAsync(callback, assetPath); - signaller.acquire(); - } - else - { - AsyncStatObjLoadCallback(asset, gEnv->p3DEngine->LoadStatObjAutoRef(assetPath)); - } - } - else - { - _smart_ptr statObj = gEnv->p3DEngine->LoadStatObjAutoRef(assetPath); - - if (statObj) - { - meshAsset->m_statObj = statObj; - } - else - { -#if defined(AZ_ENABLE_TRACING) - AZStd::string assetDescription = asset.GetId().ToString(); - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetDescription, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetPathById, asset.GetId()); - AZ_Error("MeshAssetHandler", false, "Failed to load mesh asset \"%s\".", assetDescription.c_str()); -#endif // AZ_ENABLE_TRACING - } - } - - return AZ::Data::AssetHandler::LoadResult::LoadComplete; - } - return AZ::Data::AssetHandler::LoadResult::Error; - } - - void MeshAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr) - { - delete ptr; - } - - void MeshAssetHandler::GetHandledAssetTypes(AZStd::vector& assetTypes) - { - assetTypes.push_back(AZ::AzTypeInfo::Uuid()); - } - - void MeshAssetHandler::Register() - { - AZ_Assert(AZ::Data::AssetManager::IsReady(), "Asset manager isn't ready!"); - AZ::Data::AssetManager::Instance().RegisterHandler(this, AZ::AzTypeInfo::Uuid()); - - AZ::AssetTypeInfoBus::Handler::BusConnect(AZ::AzTypeInfo::Uuid()); - } - - void MeshAssetHandler::Unregister() - { - AZ::AssetTypeInfoBus::Handler::BusDisconnect(AZ::AzTypeInfo::Uuid()); - - if (AZ::Data::AssetManager::IsReady()) - { - AZ::Data::AssetManager::Instance().UnregisterHandler(this); - } - } - - AZ::Data::AssetType MeshAssetHandler::GetAssetType() const - { - return AZ::AzTypeInfo::Uuid(); - } - - const char* MeshAssetHandler::GetAssetTypeDisplayName() const - { - return "Static Mesh"; - } - - const char* MeshAssetHandler::GetGroup() const - { - return "Geometry"; - } - - const char* MeshAssetHandler::GetBrowserIcon() const - { - return "Icons/Components/StaticMesh.svg"; - } - - AZ::Uuid MeshAssetHandler::GetComponentTypeId() const - { - return AZ::Uuid("{FC315B86-3280-4D03-B4F0-5553D7D08432}"); - } - - void MeshAssetHandler::GetAssetTypeExtensions(AZStd::vector& extensions) - { - extensions.push_back(CRY_GEOMETRY_FILE_EXT); - } - -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.h b/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.h deleted file mode 100644 index 00936316f5..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/MeshAssetHandler.h +++ /dev/null @@ -1,97 +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 -#include -#include - -struct ICVar; - -namespace LmbrCentral -{ - static const char* s_meshAssetHandler_AsyncCvar = "az_Asset_EnableAsyncMeshLoading"; - - /** - * Base class for mesh asset handlers. Contains shared utilities and functionality. - */ - class MeshAssetHandlerHelper - { - public: - - MeshAssetHandlerHelper(); - - protected: - - /** - * Removes the asset alias from a string - * - * StatObjs, CharacterInstances and GeometryCaches are stored in - * dictionaries by their path which is not aliased like the new AZ systems. - * To look up mesh instances we need the un-aliased path. - * - * This method assumes that the alias will be at the beginning of the string. - * - * @param assetPath The asset path string to remove the alias from - */ - void StripAssetAlias(const char*& assetPath); - - static const AZStd::string s_assetAliasToken; //< The token used to strip the asset alias in StripAssetAlias - - ICVar* GetAsyncLoadCVar(); - ICVar* m_asyncLoadCvar; - }; - - /** - * Handler for static mesh assets (cgf). - */ - class MeshAssetHandler - : public AZ::Data::AssetHandler - , public AZ::AssetTypeInfoBus::Handler - , private MeshAssetHandlerHelper - { - public: - - AZ_CLASS_ALLOCATOR(MeshAssetHandler, AZ::SystemAllocator, 0); - - ~MeshAssetHandler() override; - - ////////////////////////////////////////////////////////////////////////////////////////////// - // AZ::Data::AssetHandler - AZ::Data::AssetPtr CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override; - void GetCustomAssetStreamInfoForLoad(AZ::Data::AssetStreamInfo& streamInfo) override; - AZ::Data::AssetHandler::LoadResult LoadAssetData( - const AZ::Data::Asset& asset, - AZStd::shared_ptr stream, - const AZ::Data::AssetFilterCB& assetLoadFilterCB) override; - AZ::Data::AssetId AssetMissingInCatalog(const AZ::Data::Asset& asset) override; - void DestroyAsset(AZ::Data::AssetPtr ptr) override; - void GetHandledAssetTypes(AZStd::vector& assetTypes) override; - ////////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////////// - // AZ::AssetTypeInfoBus::Handler - AZ::Data::AssetType GetAssetType() const override; - const char* GetAssetTypeDisplayName() const override; - const char* GetGroup() const override; - const char* GetBrowserIcon() const override; - AZ::Uuid GetComponentTypeId() const override; - void GetAssetTypeExtensions(AZStd::vector& extensions) override; - ////////////////////////////////////////////////////////////////////////////////////////////// - - void Register(); - void Unregister(); - - AZ::Data::AssetId m_missingMeshAssetId; - }; -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.cpp b/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.cpp deleted file mode 100644 index 0ee72b62cf..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.cpp +++ /dev/null @@ -1,1228 +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 "LmbrCentral_precompiled.h" -#include "MeshComponent.h" -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -namespace LmbrCentral -{ - ////////////////////////////////////////////////////////////////////////// - - //! Handler/binding code that is required for Behavior Context reflection of EBus Notifications. - class MaterialOwnerNotificationBusBehaviorHandler : public MaterialOwnerNotificationBus::Handler, public AZ::BehaviorEBusHandler - { - public: - AZ_EBUS_BEHAVIOR_BINDER(MaterialOwnerNotificationBusBehaviorHandler, "{77705C0E-5ADE-496C-85FF-9278565E278E}", AZ::SystemAllocator - , OnMaterialOwnerReady); - - void OnMaterialOwnerReady() override - { - Call(FN_OnMaterialOwnerReady); - } - }; - - ////////////////////////////////////////////////////////////////////////// - - AZ::BehaviorParameterOverrides CreateMaterialIdDetails(AZ::BehaviorContext* behaviorContext) - { - return{ "MaterialID", "The ID of a Material slot to access, if the Owner has multiple Materials. IDs start at 1.", behaviorContext->MakeDefaultValue(1) }; - } - - AZStd::array GetMaterialParamArgs(AZ::BehaviorContext* behaviorContext) - { - AZ::BehaviorParameterOverrides getParamNameDetails = { "ParamName", "The name of the Material param to return" }; - return{ { getParamNameDetails, CreateMaterialIdDetails(behaviorContext) } }; - } - - void MeshComponent::Reflect(AZ::ReflectContext* context) - { - MeshComponentRenderNode::Reflect(context); - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Static Mesh Render Node", &MeshComponent::m_meshRenderNode); - } - - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("MeshComponentRequestBus") - ->Event("SetVisibility", &MeshComponentRequestBus::Events::SetVisibility) - ->Event("GetVisibility", &MeshComponentRequestBus::Events::GetVisibility) - ->VirtualProperty("Visibility", "GetVisibility", "SetVisibility"); - - const char* setMaterialParamTooltip = "Sets a Material param value for the given Entity. The Material will be cloned once before any changes are applied, so other instances are not affected."; - const char* getMaterialParamTooltip = "Returns a Material param value for the given Entity"; - AZ::BehaviorParameterOverrides setParamNameDetails = { "ParamName", "The name of the Material param to set" }; - const char* newValueTooltip = "The new value to apply"; - - behaviorContext->EBus("MaterialOwnerRequestBus", nullptr, "Includes functions for Components that have a Material such as Mesh Component, Decal Component, etc.") - ->Attribute(AZ::Script::Attributes::Category, "Rendering") - ->Event("IsMaterialOwnerReady", &MaterialOwnerRequestBus::Events::IsMaterialOwnerReady) - ->Attribute(AZ::Script::Attributes::ToolTip, "Indicates whether the Material Owner is fully initialized, and is ready for Material requests") - ->Event("SetMaterial", &MaterialOwnerRequestBus::Events::SetMaterialHandle) - ->Attribute(AZ::Script::Attributes::ToolTip, "Sets an Entity's Material") - ->Event("GetMaterial", &MaterialOwnerRequestBus::Events::GetMaterialHandle) - ->Attribute(AZ::Script::Attributes::ToolTip, "Returns an Entity's current Material") - ->Event("SetParamVector4", &MaterialOwnerRequestBus::Events::SetMaterialParamVector4, { { setParamNameDetails, { "Vector4", newValueTooltip }, CreateMaterialIdDetails(behaviorContext) } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Event("SetParamVector3", &MaterialOwnerRequestBus::Events::SetMaterialParamVector3, { { setParamNameDetails, { "Vector3", newValueTooltip }, CreateMaterialIdDetails(behaviorContext) } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Event("SetParamColor", &MaterialOwnerRequestBus::Events::SetMaterialParamColor, { { setParamNameDetails, { "Color" , newValueTooltip }, CreateMaterialIdDetails(behaviorContext) } }) - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Event("SetParamNumber", &MaterialOwnerRequestBus::Events::SetMaterialParamFloat, { { setParamNameDetails, { "Number" , newValueTooltip }, CreateMaterialIdDetails(behaviorContext) } }) // Using ParamNumber instead of ParamFloat because in Script Canvas all primitives are just "numbers" - ->Attribute(AZ::Script::Attributes::ToolTip, setMaterialParamTooltip) - ->Event("GetParamVector4", &MaterialOwnerRequestBus::Events::GetMaterialParamVector4, GetMaterialParamArgs(behaviorContext)) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Event("GetParamVector3", &MaterialOwnerRequestBus::Events::GetMaterialParamVector3, GetMaterialParamArgs(behaviorContext)) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Event("GetParamColor", &MaterialOwnerRequestBus::Events::GetMaterialParamColor, GetMaterialParamArgs(behaviorContext)) - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip) - ->Event("GetParamNumber", &MaterialOwnerRequestBus::Events::GetMaterialParamFloat, GetMaterialParamArgs(behaviorContext)) // Using ParamNumber instead of ParamFloat because in Script Canvas all primitives are just "numbers" - ->Attribute(AZ::Script::Attributes::ToolTip, getMaterialParamTooltip); - - behaviorContext->EBus("MaterialOwnerNotificationBus", nullptr, "Provides notifications from Components that have a Material such as Mesh Component, Decal Component, etc.") - ->Attribute(AZ::Script::Attributes::Category, "Rendering") - ->Handler() - ; - - behaviorContext->Class()->RequestBus("MeshComponentRequestBus"); - } - } - - - ////////////////////////////////////////////////////////////////////////// - - void MeshComponentRenderNode::MeshRenderOptions::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - - if (serializeContext) - { - serializeContext->Class() - ->Version(5, &VersionConverter) - ->Field("Opacity", &MeshComponentRenderNode::MeshRenderOptions::m_opacity) - ->Field("MaxViewDistance", &MeshComponentRenderNode::MeshRenderOptions::m_maxViewDist) - ->Field("ViewDistanceMultiplier", &MeshComponentRenderNode::MeshRenderOptions::m_viewDistMultiplier) - ->Field("LODRatio", &MeshComponentRenderNode::MeshRenderOptions::m_lodRatio) - ->Field("CastShadows", &MeshComponentRenderNode::MeshRenderOptions::m_castShadows) - ->Field("LODBBoxBased", &MeshComponentRenderNode::MeshRenderOptions::m_lodBoundingBoxBased) - ->Field("UseVisAreas", &MeshComponentRenderNode::MeshRenderOptions::m_useVisAreas) - ->Field("RainOccluder", &MeshComponentRenderNode::MeshRenderOptions::m_rainOccluder) - ->Field("AffectDynamicWater", &MeshComponentRenderNode::MeshRenderOptions::m_affectDynamicWater) - ->Field("ReceiveWind", &MeshComponentRenderNode::MeshRenderOptions::m_receiveWind) - ->Field("AcceptDecals", &MeshComponentRenderNode::MeshRenderOptions::m_acceptDecals) - ->Field("AffectNavmesh", &MeshComponentRenderNode::MeshRenderOptions::m_affectNavmesh) - ->Field("VisibilityOccluder", &MeshComponentRenderNode::MeshRenderOptions::m_visibilityOccluder) - ->Field("DynamicMesh", &MeshComponentRenderNode::MeshRenderOptions::m_dynamicMesh) - ->Field("AffectsGI", &MeshComponentRenderNode::MeshRenderOptions::m_affectGI) - ; - } - } - - bool MeshComponentRenderNode::MeshRenderOptions::VersionConverter(AZ::SerializeContext& context, - AZ::SerializeContext::DataElementNode& classElement) - { - // conversion from version 1: - // - Remove Bloom (m_allowBloom) - // - Remove MotionBlur (m_allowMotionBlur) - // - Remove DepthTest (m_depthTest) - if (classElement.GetVersion() <= 1) - { - classElement.RemoveElementByName(AZ_CRC("Bloom", 0xc6cd7d1b)); - classElement.RemoveElementByName(AZ_CRC("MotionBlur", 0x917cdb53)); - classElement.RemoveElementByName(AZ_CRC("DepthTest", 0x532f68b9)); - } - - // conversion from version 2: - // - Remove IndoorOnly (m_indoorOnly) - if (classElement.GetVersion() <= 2) - { - classElement.RemoveElementByName(AZ_CRC("IndoorOnly", 0xc8ab6ddb)); - } - - if (classElement.GetVersion() <= 3) - { - classElement.RemoveElementByName(AZ_CRC("CastLightmapShadows", 0x10ce0bf8)); - int index = classElement.FindElement(AZ_CRC("CastDynamicShadows", 0x55c75b43)); - AZ::SerializeContext::DataElementNode& shadowNode = classElement.GetSubElement(index); - shadowNode.SetName("CastShadows"); - } - - // conversion from version 4: - // - Set "CastShadows" to false if "Opacity" is less than 1.0f, in order to not break old assets. - // The new system ignores opacity for shadow casting and relies only on the "CastShadows" flag. - if (classElement.GetVersion() <= 4) - { - float opacity; - int opacityElementIndex = classElement.FindElement(AZ_CRC("Opacity", 0x43fd6d66)); - AZ::SerializeContext::DataElementNode& opacityNode = classElement.GetSubElement(opacityElementIndex); - opacityNode.GetData(opacity); - - if (opacity < 1.0f) - { - int castShadowsElementIndex = classElement.FindElement(AZ_CRC("CastShadows", 0xbe687463)); - AZ::SerializeContext::DataElementNode& castShadowsNode = classElement.GetSubElement(castShadowsElementIndex); - castShadowsNode.SetData(context, false); - } - } - - return true; - } - - bool MeshComponentRenderNode::MeshRenderOptions::IsStatic() const - { - return (m_hasStaticTransform && !m_dynamicMesh && !m_receiveWind); - } - - bool MeshComponentRenderNode::MeshRenderOptions::AffectsGi() const - { - return m_affectGI && IsStatic(); - } - - AZ::Crc32 MeshComponentRenderNode::MeshRenderOptions::StaticPropertyVisibility() const - { - return IsStatic() ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide; - } - - void MeshComponentRenderNode::Reflect(AZ::ReflectContext* context) - { - MeshRenderOptions::Reflect(context); - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Visible", &MeshComponentRenderNode::m_visible) - ->Field("Static Mesh", &MeshComponentRenderNode::m_meshAsset) - ->Field("Material Override", &MeshComponentRenderNode::m_material) - ->Field("Render Options", &MeshComponentRenderNode::m_renderOptions) - ; - } - } - - float MeshComponentRenderNode::GetDefaultMaxViewDist() - { - if (gEnv && gEnv->p3DEngine) - { - return gEnv->p3DEngine->GetMaxViewDistance(false); - } - - // In the editor and the game, the dynamic lookup above should *always* hit. - // This case essentially means no renderer (not even the null renderer) is present. - return FLT_MAX; - } - - MeshComponentRenderNode::MeshRenderOptions::MeshRenderOptions() - : m_opacity(1.f) - , m_viewDistMultiplier(1.f) - , m_lodRatio(100) - , m_useVisAreas(true) - , m_castShadows(true) - , m_lodBoundingBoxBased(false) - , m_rainOccluder(true) - , m_affectNavmesh(true) - , m_affectDynamicWater(false) - , m_acceptDecals(true) - , m_receiveWind(false) - , m_visibilityOccluder(false) - , m_dynamicMesh(false) - , m_hasStaticTransform(false) - , m_affectGI(true) - { - m_maxViewDist = GetDefaultMaxViewDist(); - } - - MeshComponentRenderNode::MeshComponentRenderNode() - : m_statObj(nullptr) - , m_materialOverride(nullptr) - , m_auxiliaryRenderFlags(0) - , m_auxiliaryRenderFlagsHistory(0) - , m_lodDistance(0.f) - , m_lodDistanceScaled(FLT_MAX / (SMeshLodInfo::s_nMaxLodCount + 1)) // defualt overflow prevention - it is scaled by (SMeshLodInfo::s_nMaxLodCount + 1) - , m_lodDistanceScaleValue(1.0f) - , m_isRegisteredWithRenderer(false) - , m_objectMoved(false) - , m_meshAsset(AZ::Data::AssetLoadBehavior::QueueLoad) - , m_visible(true) - { - m_localBoundingBox.Reset(); - m_worldBoundingBox.Reset(); - m_worldTransform = AZ::Transform::CreateIdentity(); - m_renderTransform = Matrix34::CreateIdentity(); - } - - MeshComponentRenderNode::~MeshComponentRenderNode() - { - DestroyMesh(); - } - - void MeshComponentRenderNode::CopyPropertiesTo(MeshComponentRenderNode& rhs) const - { - rhs.m_visible = m_visible; - rhs.m_materialOverride = m_materialOverride; - rhs.m_meshAsset = m_meshAsset; - rhs.m_material = m_material; - rhs.m_renderOptions = m_renderOptions; - } - - void MeshComponentRenderNode::AttachToEntity(AZ::EntityId id) - { - if (AZ::TransformNotificationBus::Handler::BusIsConnectedId(m_renderOptions.m_attachedToEntityId)) - { - AZ::TransformNotificationBus::Handler::BusDisconnect(m_renderOptions.m_attachedToEntityId); - } - - if (m_modificationHelper.IsConnected()) - { - m_modificationHelper.Disconnect(); - } - - if (id.IsValid()) - { - if (!AZ::TransformNotificationBus::Handler::BusIsConnectedId(id)) - { - AZ::TransformNotificationBus::Handler::BusConnect(id); - } - - auto transformHandler = AZ::TransformBus::FindFirstHandler(id); - - UpdateWorldTransform(transformHandler->GetWorldTM()); - - AzFramework::EntityBoundsUnionRequestBus::Broadcast( - &AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); - - m_modificationHelper.Connect(id); - } - - m_renderOptions.m_attachedToEntityId = id; - } - - void MeshComponentRenderNode::OnAssetPropertyChanged() - { - if (HasMesh()) - { - DestroyMesh(); - } - - AZ::Data::AssetBus::Handler::BusDisconnect(); - - CreateMesh(); - AzFramework::RenderGeometry::IntersectionNotificationBus::Event(m_contextId, - &AzFramework::RenderGeometry::IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - void MeshComponentRenderNode::RefreshRenderState() - { - if (gEnv->IsEditor()) - { - UpdateLocalBoundingBox(); - - AZ::Transform parentTransform = AZ::Transform::CreateIdentity(); - EBUS_EVENT_ID_RESULT(parentTransform, m_renderOptions.m_attachedToEntityId, AZ::TransformBus, GetWorldTM); - OnTransformChanged(AZ::Transform::CreateIdentity(), parentTransform); - - if (HasMesh()) - { - // Re-register with the renderer, as some render settings/flags require it. - // Note that this is editor-only behavior (hence the guard above). - if (m_isRegisteredWithRenderer) - { - RegisterWithRenderer(false); - RegisterWithRenderer(true); - } - } - } - } - - void MeshComponentRenderNode::SetTransformStaticState(bool isStatic) - { - m_renderOptions.m_hasStaticTransform = isStatic; - } - - const AZ::Transform& MeshComponentRenderNode::GetTransform() const - { - return m_worldTransform; - } - - void MeshComponentRenderNode::SetAuxiliaryRenderFlags(uint32 flags) - { - m_auxiliaryRenderFlags = flags; - m_auxiliaryRenderFlagsHistory |= flags; - } - - void MeshComponentRenderNode::UpdateAuxiliaryRenderFlags(bool on, uint32 mask) - { - if (on) - { - m_auxiliaryRenderFlags |= mask; - } - else - { - m_auxiliaryRenderFlags &= ~mask; - } - - m_auxiliaryRenderFlagsHistory |= mask; - } - - bool MeshComponentRenderNode::IsReady() const - { - return HasMesh(); - } - - void MeshComponentRenderNode::CreateMesh() - { - if (m_meshAsset.GetId().IsValid()) - { - if (!AZ::Data::AssetBus::Handler::BusIsConnected()) - { - AZ::Data::AssetBus::Handler::BusConnect(m_meshAsset.GetId()); - } - - m_meshAsset.QueueLoad(); - } - } - - void MeshComponentRenderNode::DestroyMesh() - { - AZ::Data::AssetBus::Handler::BusDisconnect(); - - RegisterWithRenderer(false); - m_statObj = nullptr; - - EBUS_EVENT_ID(m_renderOptions.m_attachedToEntityId, MeshComponentNotificationBus, OnMeshDestroyed); - - m_meshAsset.Release(); - } - - bool MeshComponentRenderNode::HasMesh() const - { - return m_statObj != nullptr; - } - - void MeshComponentRenderNode::SetMeshAsset(const AZ::Data::AssetId& id) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(id, m_meshAsset.GetAutoLoadBehavior()); - - if (asset) - { - m_meshAsset = asset; - OnAssetPropertyChanged(); - } - } - - void MeshComponentRenderNode::GetMemoryUsage(class ICrySizer* pSizer) const - { - pSizer->AddObjectSize(this); - } - - float MeshComponentRenderNode::GetUniformScale() - { - AZ::Vector3 scales = m_worldTransform.GetScale(); - AZ_Assert((scales.GetX() == scales.GetY()) && (scales.GetY() == scales.GetZ()), "Scales are not uniform"); - return scales.GetX(); - } - - float MeshComponentRenderNode::GetColumnScale(int column) - { - return m_worldTransform.GetScale().GetElement(column); - } - - void MeshComponentRenderNode::OnTransformChanged(const AZ::Transform&, const AZ::Transform& parentWorld) - { - // The entity to which we're attached has moved. - UpdateWorldTransform(parentWorld); - AzFramework::RenderGeometry::IntersectionNotificationBus::Event(m_contextId, - &AzFramework::RenderGeometry::IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - - void MeshComponentRenderNode::OnAssetReady(AZ::Data::Asset asset) - { - if (asset == m_meshAsset) - { - m_meshAsset = asset; - BuildRenderMesh(); - - if (HasMesh()) - { - const AZStd::string& materialOverridePath = m_material.GetAssetPath(); - if (!materialOverridePath.empty()) - { - m_materialOverride = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(materialOverridePath.c_str()); - - AZ_Warning("MeshComponent", m_materialOverride != gEnv->p3DEngine->GetMaterialManager()->GetDefaultMaterial(), - "Failed to load override Material \"%s\".", - materialOverridePath.c_str()); - } - else - { - m_materialOverride = nullptr; - } - - UpdateLocalBoundingBox(); - UpdateLodDistance(gEnv->p3DEngine->GetFrameLodInfo()); - RegisterWithRenderer(true); - - // Inform listeners that the mesh has been changed - LmbrCentral::MeshComponentNotificationBus::Event(m_renderOptions.m_attachedToEntityId, &LmbrCentral::MeshComponentNotifications::OnMeshCreated, asset); - AzFramework::RenderGeometry::IntersectionNotificationBus::Event(m_contextId, &AzFramework::RenderGeometry::IntersectionNotifications::OnGeometryChanged, GetEntityId()); - } - } - } - - void MeshComponentRenderNode::OnAssetReloaded(AZ::Data::Asset asset) - { - // note that this also corrects the assetId if it is incorrect - do not remove the following line - // even if you call OnAssetReady - OnAssetReady(asset); - } - - void MeshComponentRenderNode::UpdateWorldTransform(const AZ::Transform& entityTransform) - { - m_worldTransform = entityTransform; - - m_renderTransform = AZTransformToLYTransform(m_worldTransform); - - UpdateWorldBoundingBox(); - if (m_isRegisteredWithRenderer && m_renderOptions.AffectsGi()) - { - GiRegistrationBus::Broadcast(&GiRegistration::UpsertToGi, - m_renderOptions.m_attachedToEntityId, - m_worldTransform, - CalculateWorldAABB(), - m_meshAsset, - GetMaterial()); - } - - m_objectMoved = true; - } - - void MeshComponentRenderNode::UpdateLocalBoundingBox() - { - m_localBoundingBox.Reset(); - - if (HasMesh()) - { - m_localBoundingBox.Add(m_statObj->GetAABB()); - } - - AzFramework::EntityBoundsUnionRequestBus::Broadcast( - &AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); - - UpdateWorldBoundingBox(); - } - - void MeshComponentRenderNode::UpdateWorldBoundingBox() - { - m_worldBoundingBox.SetTransformedAABB(m_renderTransform, m_localBoundingBox); - - if (m_isRegisteredWithRenderer) - { - // Re-register with the renderer to update culling info - gEnv->p3DEngine->RegisterEntity(this); - } - } - - void MeshComponentRenderNode::SetVisible(bool isVisible) - { - if (m_visible != isVisible) - { - m_visible = isVisible; - RegisterWithRenderer(false); - RegisterWithRenderer(true); - } - } - - bool MeshComponentRenderNode::GetVisible() - { - return m_visible; - } - - void MeshComponentRenderNode::RegisterWithRenderer(bool registerWithRenderer) - { - if (gEnv && gEnv->p3DEngine) - { - if (registerWithRenderer) - { - if (!m_isRegisteredWithRenderer) - { - ApplyRenderOptions(); - - gEnv->p3DEngine->RegisterEntity(this); - - if (m_renderOptions.AffectsGi()) - { - GiRegistrationBus::Broadcast(&GiRegistration::UpsertToGi, - m_renderOptions.m_attachedToEntityId, - m_worldTransform, - CalculateWorldAABB(), - m_meshAsset, - GetMaterial()); - } - - m_isRegisteredWithRenderer = true; - } - } - else - { - if (m_isRegisteredWithRenderer) - { - gEnv->p3DEngine->FreeRenderNodeState(this); - - GiRegistrationBus::Broadcast(&GiRegistration::RemoveFromGi, - m_renderOptions.m_attachedToEntityId); - - m_isRegisteredWithRenderer = false; - } - } - } - } - - namespace MeshInternal - { - void UpdateRenderFlag(bool enable, int mask, unsigned int& flags) - { - if (enable) - { - flags |= mask; - } - else - { - flags &= ~mask; - } - } - } - - void MeshComponentRenderNode::ApplyRenderOptions() - { - using MeshInternal::UpdateRenderFlag; - unsigned int flags = GetRndFlags(); - flags |= ERF_COMPONENT_ENTITY; - - // Turn off any flag which has ever been set via auxiliary render flags - UpdateRenderFlag(false, m_auxiliaryRenderFlagsHistory, flags); - - // Update flags according to current render settings - UpdateRenderFlag(m_renderOptions.m_useVisAreas == false, ERF_OUTDOORONLY, flags); - UpdateRenderFlag(m_renderOptions.m_castShadows, ERF_CASTSHADOWMAPS | ERF_HAS_CASTSHADOWMAPS, flags); - UpdateRenderFlag(m_renderOptions.m_rainOccluder && m_renderOptions.IsStatic(), ERF_RAIN_OCCLUDER, flags); - UpdateRenderFlag(m_visible == false, ERF_HIDDEN, flags); - UpdateRenderFlag(m_renderOptions.m_receiveWind, ERF_RECVWIND, flags); - UpdateRenderFlag(m_renderOptions.m_visibilityOccluder && m_renderOptions.IsStatic(), ERF_GOOD_OCCLUDER, flags); - //Dynamic meshes shouldn't affect the navmeshes. If that decision is changed we should change this line to no longer require - //static and note that the flag is tied to the negation of the navemesh boolean. - //Also see the editormeshcomponent.cpp AffectNavemesh function. - UpdateRenderFlag(!(m_renderOptions.m_affectNavmesh && m_renderOptions.IsStatic()), ERF_EXCLUDE_FROM_TRIANGULATION, flags); - UpdateRenderFlag(false == m_renderOptions.m_affectDynamicWater && m_renderOptions.IsStatic(), ERF_NODYNWATER, flags); - UpdateRenderFlag(false == m_renderOptions.m_acceptDecals, ERF_NO_DECALNODE_DECALS, flags); - - UpdateRenderFlag(m_renderOptions.m_lodBoundingBoxBased, ERF_LOD_BBOX_BASED, flags); - - // Apply current auxiliary render flags - UpdateRenderFlag(true, m_auxiliaryRenderFlags, flags); - - m_fWSMaxViewDist = m_renderOptions.m_maxViewDist; - - SetViewDistanceMultiplier(m_renderOptions.m_viewDistMultiplier); - - SetLodRatio(static_cast(m_renderOptions.m_lodRatio)); - - SetRndFlags(flags); - } - - CLodValue MeshComponentRenderNode::ComputeLOD( int wantedLod, const SRenderingPassInfo& passInfo) - { - // Default values as per the CVar - default fade going between 2 and 8 meters with dissolve enabled - float dissolveDistMin = 2.0f; - float dissolveDistMax = 8.0f; - int dissolveEnabled = 1; - - if (gEnv && gEnv->pConsole) - { - static ICVar* dissolveDistMinCvar = gEnv->pConsole->GetCVar("e_DissolveDistMin"); - static ICVar* dissolveDistMaxCvar = gEnv->pConsole->GetCVar("e_DissolveDistMax"); - static ICVar* dissolveEnabledCvar = gEnv->pConsole->GetCVar("e_Dissolve"); - - dissolveDistMin = dissolveDistMinCvar->GetFVal(); - dissolveDistMax = dissolveDistMaxCvar->GetFVal(); - dissolveEnabled = dissolveEnabledCvar->GetIVal() ; - } - - const Vec3 cameraPos = passInfo.GetCamera().GetPosition(); - const float entityDistance = sqrt_tpl(Distance::Point_AABBSq(cameraPos, GetBBox())) * passInfo.GetZoomFactor(); - - wantedLod = CLAMP(wantedLod, m_statObj->GetMinUsableLod(), SMeshLodInfo::s_nMaxLodCount); - int currentLod = m_statObj->FindNearesLoadedLOD(wantedLod, true); - - if (dissolveEnabled && passInfo.IsGeneralPass()) - { - float invDissolveDist = 1.0f / CLAMP(0.1f * m_fWSMaxViewDist, dissolveDistMin, dissolveDistMax ); - int nextLod = m_statObj->FindNearesLoadedLOD(currentLod + 1, true); - - // If the user chose to base LOD switch on bounding boxes, then we do not use the geometric mean computed at init. - if (GetRndFlags() & ERF_LOD_BBOX_BASED) - { - const float lodRatio = GetLodRatioNormalized(); - if (lodRatio > 0.0f) - { - // We do not use a geometric mean per object but a global value for all objects. - static ICVar* lodBoundingBoxDistanceMultiplier = gEnv->pConsole->GetCVar("e_LodBoundingBoxDistanceMultiplier"); - - m_lodDistanceScaled = lodBoundingBoxDistanceMultiplier->GetFVal() * m_lodDistanceScaleValue; - } - } - else - { - m_lodDistanceScaled = m_lodDistance * m_lodDistanceScaleValue; - } - - float lodDistance = m_lodDistanceScaled * (currentLod + 1); - uint8 dissolveRatio255 = (uint8)SATURATEB((1.0f + (entityDistance - lodDistance) * invDissolveDist) * 255.f); - - if (dissolveRatio255 == 255) - { - return CLodValue(nextLod, 0, -1); - } - return CLodValue(currentLod, dissolveRatio255, nextLod); - } - - return CLodValue(currentLod); - } - - AZ::Aabb MeshComponentRenderNode::CalculateWorldAABB() const - { - AZ::Aabb aabb = AZ::Aabb::CreateNull(); - if (!m_worldBoundingBox.IsReset()) - { - aabb.AddPoint(LYVec3ToAZVec3(m_worldBoundingBox.min)); - aabb.AddPoint(LYVec3ToAZVec3(m_worldBoundingBox.max)); - } - return aabb; - } - - AZ::Aabb MeshComponentRenderNode::CalculateLocalAABB() const - { - AZ::Aabb aabb = AZ::Aabb::CreateNull(); - if (!m_localBoundingBox.IsReset()) - { - aabb.AddPoint(LYVec3ToAZVec3(m_localBoundingBox.min)); - aabb.AddPoint(LYVec3ToAZVec3(m_localBoundingBox.max)); - } - return aabb; - } - - /*IRenderNode*/ void MeshComponentRenderNode::Render(const struct SRendParams& inRenderParams, const struct SRenderingPassInfo& passInfo) - { - if (!HasMesh()) - { - return; - } - - if (!m_modificationHelper.GetMeshModified()) - { - IStatObj* obj = GetEntityStatObj(); - int subObjectCount = obj->GetSubObjectCount(); - - AZStd::function getSubObject; - if (subObjectCount == 0) - { - getSubObject = [obj](size_t index) - { - if (index > 0) - { - AZ_Warning("MeshComponentRenderNode", false, "Mesh indices out of range"); - return static_cast(nullptr); - } - return obj; - }; - } - else - { - getSubObject = [obj, subObjectCount](size_t index) - { - if (index >= subObjectCount) - { - AZ_Warning("MeshComponentRenderNode", false, "Mesh indices out of range"); - return static_cast(nullptr); - } - return obj->GetSubObject(index)->pStatObj; - }; - } - - for (const LmbrCentral::MeshModificationRequestHelper::MeshLODPrimIndex& meshIndices : m_modificationHelper.MeshesToEdit()) - { - if (meshIndices.lodIndex != 0) - { - continue; - } - - IStatObj* subObject = getSubObject(meshIndices.primitiveIndex); - if (!subObject) - { - continue; - } - - MeshModificationNotificationBus::Event( - GetEntityId(), - &MeshModificationNotificationBus::Events::ModifyMesh, - meshIndices.lodIndex, - meshIndices.primitiveIndex, - subObject->GetRenderMesh()); - } - - m_modificationHelper.SetMeshModified(true); - } - - SRendParams rParams(inRenderParams); - - // Assign a unique pInstance pointer, otherwise effects involving SRenderObjData will not work for this object. CEntityObject::Render does this for legacy entities. - rParams.pInstance = this; - - rParams.fAlpha = m_renderOptions.m_opacity; - - _smart_ptr previousMaterial = rParams.pMaterial; - const int previousObjectFlags = rParams.dwFObjFlags; - - if (m_materialOverride) - { - rParams.pMaterial = m_materialOverride; - } - - if (m_objectMoved) - { - rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT; - m_objectMoved = false; - } - - rParams.pMatrix = &m_renderTransform; - rParams.bForceDrawStatic = !m_renderOptions.m_dynamicMesh; - if (rParams.pMatrix->IsValid()) - { - rParams.lodValue = ComputeLOD(inRenderParams.lodValue.LodA(), passInfo); - m_statObj->Render(rParams, passInfo); - } - - rParams.pMaterial = previousMaterial; - rParams.dwFObjFlags = previousObjectFlags; - } - - /*IRenderNode*/ bool MeshComponentRenderNode::GetLodDistances(const SFrameLodInfo& frameLodInfo, float* distances) const - { - const float lodRatio = GetLodRatioNormalized(); - if (lodRatio > 0.0f) - { - const float distMultiplier = 1.f / (lodRatio * frameLodInfo.fTargetSize); - - for (int lodIndex = 0; lodIndex < SMeshLodInfo::s_nMaxLodCount; ++lodIndex) - { - distances[lodIndex] = m_lodDistance * (lodIndex + 1) * distMultiplier; - } - } - else - { - for (int lodIndex = 0; lodIndex < SMeshLodInfo::s_nMaxLodCount; ++lodIndex) - { - distances[lodIndex] = FLT_MAX; - } - } - return true; - } - - void MeshComponentRenderNode::UpdateLodDistance(const SFrameLodInfo& frameLodInfo) - { - SMeshLodInfo lodInfo; - - if (HasMesh()) - { - m_statObj->ComputeGeometricMean(lodInfo); - } - - m_lodDistance = sqrt(lodInfo.fGeometricMean); - - // The following computation need to stay in accordance with the 'GetLodDistances' formula. - const float lodRatio = GetLodRatioNormalized(); - if (lodRatio > 0.0f) - { - m_lodDistanceScaled = m_lodDistance / (lodRatio * frameLodInfo.fTargetSize); - m_lodDistanceScaleValue = 1.0f / (lodRatio * frameLodInfo.fTargetSize); - } - } - - /*IRenderNode*/ EERType MeshComponentRenderNode::GetRenderNodeType() - { - return m_renderOptions.IsStatic() ? eERType_StaticMeshRenderComponent : eERType_DynamicMeshRenderComponent; - } - - /*IRenderNode*/ bool MeshComponentRenderNode::CanExecuteRenderAsJob() - { - return !m_renderOptions.m_dynamicMesh - && !m_renderOptions.m_receiveWind - && m_modificationHelper.MeshesToEdit().empty(); - } - - /*IRenderNode*/ const char* MeshComponentRenderNode::GetName() const - { - return "MeshComponentRenderNode"; - } - - /*IRenderNode*/ const char* MeshComponentRenderNode::GetEntityClassName() const - { - return "MeshComponentRenderNode"; - } - - /*IRenderNode*/ Vec3 MeshComponentRenderNode::GetPos([[maybe_unused]] bool bWorldOnly /*= true*/) const - { - return m_renderTransform.GetTranslation(); - } - - /*IRenderNode*/ const AABB MeshComponentRenderNode::GetBBox() const - { - return m_worldBoundingBox; - } - - /*IRenderNode*/ void MeshComponentRenderNode::SetBBox(const AABB& WSBBox) - { - m_worldBoundingBox = WSBBox; - } - - /*IRenderNode*/ void MeshComponentRenderNode::OffsetPosition(const Vec3& delta) - { - // Recalculate local transform - AZ::Transform localTransform = AZ::Transform::CreateIdentity(); - EBUS_EVENT_ID_RESULT(localTransform, m_renderOptions.m_attachedToEntityId, AZ::TransformBus, GetLocalTM); - - localTransform.SetTranslation(localTransform.GetTranslation() + LYVec3ToAZVec3(delta)); - EBUS_EVENT_ID(m_renderOptions.m_attachedToEntityId, AZ::TransformBus, SetLocalTM, localTransform); - - m_objectMoved = true; - } - - /*IRenderNode*/ void MeshComponentRenderNode::SetMaterial(_smart_ptr pMat) - { - m_materialOverride = pMat; - - if (pMat) - { - m_material.SetAssetPath(pMat->GetName()); - } - else - { - // If no material is provided, we intend to reset to the original material so we treat - // it as an asset reset to recreate the mesh. - m_material.SetAssetPath(""); - OnAssetPropertyChanged(); - } - } - - /*IRenderNode*/ _smart_ptr MeshComponentRenderNode::GetMaterial([[maybe_unused]] Vec3* pHitPos /*= nullptr*/) - { - if (m_materialOverride) - { - return m_materialOverride; - } - - if (HasMesh()) - { - return m_statObj->GetMaterial(); - } - - return nullptr; - } - - /*IRenderNode*/ _smart_ptr MeshComponentRenderNode::GetMaterialOverride() - { - return m_materialOverride; - } - - /*IRenderNode*/ float MeshComponentRenderNode::GetMaxViewDist() - { - return(m_renderOptions.m_maxViewDist * 0.75f * GetViewDistanceMultiplier()); - } - - /*IRenderNode*/ IStatObj* MeshComponentRenderNode::GetEntityStatObj(unsigned int nPartId, [[maybe_unused]] unsigned int nSubPartId, Matrix34A* pMatrix, [[maybe_unused]] bool bReturnOnlyVisible) - { - if (0 == nPartId) - { - if (pMatrix) - { - *pMatrix = m_renderTransform; - } - - return m_statObj; - } - - return nullptr; - } - - /*IRenderNode*/ _smart_ptr MeshComponentRenderNode::GetEntitySlotMaterial(unsigned int nPartId, [[maybe_unused]] bool bReturnOnlyVisible, [[maybe_unused]] bool* pbDrawNear) - { - if (0 == nPartId) - { - return m_materialOverride; - } - - return nullptr; - } - - ////////////////////////////////////////////////////////////////////////// - // MeshComponent - const float MeshComponent::s_renderNodeRequestBusOrder = 100.f; - - MeshComponent::MeshComponent() - { - m_materialBusHandler = aznew MaterialOwnerRequestBusHandlerImpl(); - } - - MeshComponent::~MeshComponent() - { - delete m_materialBusHandler; - } - - void MeshComponent::Activate() - { - m_meshRenderNode.AttachToEntity(m_entity->GetId()); - m_materialBusHandler->Activate(&m_meshRenderNode, m_entity->GetId()); - bool isStatic = false; - AZ::TransformBus::EventResult(isStatic, m_entity->GetId(), &AZ::TransformBus::Events::IsStaticTransform); - m_meshRenderNode.SetTransformStaticState(isStatic); - // Note we are purposely connecting to buses before calling m_mesh.CreateMesh(). - // m_mesh.CreateMesh() can result in events (eg: OnMeshCreated) that we want receive. - MaterialOwnerRequestBus::Handler::BusConnect(m_entity->GetId()); - MeshComponentRequestBus::Handler::BusConnect(m_entity->GetId()); - AzFramework::BoundsRequestBus::Handler::BusConnect(m_entity->GetId()); - RenderNodeRequestBus::Handler::BusConnect(m_entity->GetId()); - AzFramework::EntityContextId contextId; - AzFramework::EntityIdContextQueryBus::EventResult(contextId, GetEntityId(), &AzFramework::EntityIdContextQueries::GetOwningContextId); - AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusConnect({ GetEntityId(), contextId }); - m_meshRenderNode.SetContextId(contextId); - m_meshRenderNode.CreateMesh(); - LegacyMeshComponentRequestBus::Handler::BusConnect(GetEntityId()); - } - - void MeshComponent::Deactivate() - { - AzFramework::RenderGeometry::IntersectionRequestBus::Handler::BusDisconnect(); - - MeshComponentRequestBus::Handler::BusDisconnect(); - AzFramework::BoundsRequestBus::Handler::BusDisconnect(); - MaterialOwnerRequestBus::Handler::BusDisconnect(); - LegacyMeshComponentRequestBus::Handler::BusDisconnect(); - RenderNodeRequestBus::Handler::BusDisconnect(); - - m_meshRenderNode.DestroyMesh(); - m_meshRenderNode.AttachToEntity(AZ::EntityId()); - m_materialBusHandler->Deactivate(); - } - - AZ::Aabb MeshComponent::GetWorldBounds() - { - return m_meshRenderNode.CalculateWorldAABB(); - } - - AZ::Aabb MeshComponent::GetLocalBounds() - { - return m_meshRenderNode.CalculateLocalAABB(); - } - - void MeshComponent::SetMeshAsset(const AZ::Data::AssetId& id) - { - m_meshRenderNode.SetMeshAsset(id); - } - - bool MeshComponent::IsMaterialOwnerReady() - { - return m_materialBusHandler->IsMaterialOwnerReady(); - } - - void MeshComponent::SetMaterial(_smart_ptr material) - { - m_materialBusHandler->SetMaterial(material); - } - - _smart_ptr MeshComponent::GetMaterial() - { - return m_materialBusHandler->GetMaterial(); - } - - void MeshComponent::SetMaterialHandle(const MaterialHandle& materialHandle) - { - m_materialBusHandler->SetMaterialHandle(materialHandle); - } - - MaterialHandle MeshComponent::GetMaterialHandle() - { - return m_materialBusHandler->GetMaterialHandle(); - } - - void MeshComponent::SetMaterialParamVector4(const AZStd::string& name, const AZ::Vector4& value, int materialId) - { - m_materialBusHandler->SetMaterialParamVector4(name, value, materialId); - } - - void MeshComponent::SetMaterialParamVector3(const AZStd::string& name, const AZ::Vector3& value, int materialId) - { - m_materialBusHandler->SetMaterialParamVector3(name, value, materialId); - } - - void MeshComponent::SetMaterialParamColor(const AZStd::string& name, const AZ::Color& value, int materialId) - { - m_materialBusHandler->SetMaterialParamColor(name, value, materialId); - } - - void MeshComponent::SetMaterialParamFloat(const AZStd::string& name, float value, int materialId) - { - m_materialBusHandler->SetMaterialParamFloat(name, value, materialId); - } - - AZ::Vector4 MeshComponent::GetMaterialParamVector4(const AZStd::string& name, int materialId) - { - return m_materialBusHandler->GetMaterialParamVector4(name, materialId); - } - - AZ::Vector3 MeshComponent::GetMaterialParamVector3(const AZStd::string& name, int materialId) - { - return m_materialBusHandler->GetMaterialParamVector3(name, materialId); - } - - AZ::Color MeshComponent::GetMaterialParamColor(const AZStd::string& name, int materialId) - { - return m_materialBusHandler->GetMaterialParamColor(name, materialId); - } - - float MeshComponent::GetMaterialParamFloat(const AZStd::string& name, int materialId) - { - return m_materialBusHandler->GetMaterialParamFloat(name, materialId); - } - - IRenderNode* MeshComponent::GetRenderNode() - { - return &m_meshRenderNode; - } - - float MeshComponent::GetRenderNodeRequestBusOrder() const - { - return s_renderNodeRequestBusOrder; - } - - IStatObj* MeshComponent::GetStatObj() - { - return m_meshRenderNode.GetEntityStatObj(); - } - - AzFramework::RenderGeometry::RayResult MeshComponent::RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) - { - AzFramework::RenderGeometry::RayResult result; - if (!GetVisibility() && ray.m_onlyVisible) - { - return result; - } - - if (IStatObj* geometry = GetStatObj()) - { - const AZ::Vector3 rayDirection = (ray.m_endWorldPosition - ray.m_startWorldPosition); - const AZ::Transform& transform = m_meshRenderNode.GetTransform(); - const AZ::Transform inverseTransform = transform.GetInverse(); - - const AZ::Vector3 rayStartLocal = inverseTransform.TransformPoint(ray.m_startWorldPosition); - const AZ::Vector3 rayDistNormLocal = inverseTransform.TransformVector(rayDirection).GetNormalized(); - - SRayHitInfo hi; - hi.inReferencePoint = AZVec3ToLYVec3(rayStartLocal); - hi.inRay = Ray(hi.inReferencePoint, AZVec3ToLYVec3(rayDistNormLocal)); - hi.bInFirstHit = true; - hi.bGetVertColorAndTC = true; - if (geometry->RayIntersection(hi)) - { - AZ::Matrix3x4 invTransformMatrix = AZ::Matrix3x4::CreateFromTransform(inverseTransform); - invTransformMatrix.Transpose(); - - result.m_uv = LYVec2ToAZVec2(hi.vHitTC); - result.m_worldPosition = transform.TransformPoint(LYVec3ToAZVec3(hi.vHitPos)); - result.m_worldNormal = invTransformMatrix.Multiply3x3(LYVec3ToAZVec3(hi.vHitNormal)).GetNormalized(); - result.m_distance = (result.m_worldPosition - ray.m_startWorldPosition).GetLength(); - result.m_entityAndComponent = { GetEntityId(), GetId() }; - } - } - return result; - } - - bool MeshComponent::GetVisibility() - { - return m_meshRenderNode.GetVisible(); - } - - void MeshComponent::SetVisibility(bool isVisible) - { - m_meshRenderNode.SetVisible(isVisible); - } - - void MeshComponentRenderNode::BuildRenderMesh() - { - m_statObj = nullptr; // Release smart pointer - - MeshAsset* data = m_meshAsset.Get(); - if (!data || !data->m_statObj) - { - return; - } - - // Populate m_statObj. If the mesh doesn't require to be unique, we reuse the render mesh from the asset. If the - // mesh requires to be unique, we create a copy of the asset's render mesh since it will be modified. - - bool hasClothData = !data->m_statObj->GetClothData().empty(); - const int subObjectCount = data->m_statObj->GetSubObjectCount(); - for (int i = 0; i < subObjectCount && !hasClothData; ++i) - { - IStatObj::SSubObject* subObject = data->m_statObj->GetSubObject(i); - if (subObject && - subObject->pStatObj && - !subObject->pStatObj->GetClothData().empty()) - { - hasClothData = true; - } - } - - bool useUniqueMesh = hasClothData; - - if (useUniqueMesh) - { - // Create a copy since each mesh can be deforming differently and we need to send different meshes to render - m_statObj = data->m_statObj->Clone( /*bCloneGeometry*/ true, /*bCloneChildren*/ true, /*bMeshesOnly*/ false); - } - else - { - // Reuse the same render mesh - m_statObj = data->m_statObj; - } - } -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.h b/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.h deleted file mode 100644 index f7a7f5d861..0000000000 --- a/Gems/LmbrCentral/Code/Source/Rendering/MeshComponent.h +++ /dev/null @@ -1,393 +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 -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace LmbrCentral -{ - class MaterialOwnerRequestBusHandlerImpl; - - /*! - * RenderNode implementation responsible for integrating with the renderer. - * The node owns render flags, the mesh instance, and the render transform. - */ - class MeshComponentRenderNode - : public IRenderNode - , public AZ::TransformNotificationBus::Handler - , public AZ::Data::AssetBus::Handler - { - friend class EditorMeshComponent; - public: - using MaterialPtr = _smart_ptr < IMaterial > ; - using MeshPtr = _smart_ptr < IStatObj > ; - - AZ_TYPE_INFO(MeshComponentRenderNode, "{46FF2BC4-BEF9-4CC4-9456-36C127C310D7}"); - - MeshComponentRenderNode(); - ~MeshComponentRenderNode() override; - - void CopyPropertiesTo(MeshComponentRenderNode& rhs) const; - - //! Notifies render node which entity owns it, for subscribing to transform - //! bus, etc. - void AttachToEntity(AZ::EntityId id); - - //! Returns true after all required assets are loaded - bool IsReady() const override; - - //! Instantiate mesh instance. - void CreateMesh(); - - //! Destroy mesh instance. - void DestroyMesh(); - - //! Returns true if the node has geometry assigned. - bool HasMesh() const; - - //! Assign a new mesh asset - void SetMeshAsset(const AZ::Data::AssetId& id); - - //! Get the mesh asset - AZ::Data::Asset GetMeshAsset() { return m_meshAsset; } - - //! Invoked in the editor when the user assigns a new asset. - void OnAssetPropertyChanged(); - - //! Render the mesh - void RenderMesh(const struct SRendParams& inRenderParams, const struct SRenderingPassInfo& passInfo); - - //! Updates the render node's world transform based on the entity's. - void UpdateWorldTransform(const AZ::Transform& entityTransform); - - //! Computes world-space AABB. - AZ::Aabb CalculateWorldAABB() const; - - //! Computes local-space AABB. - AZ::Aabb CalculateLocalAABB() const; - - ////////////////////////////////////////////////////////////////////////// - // AZ::Data::AssetBus::Handler - void OnAssetReady(AZ::Data::Asset asset) override; - void OnAssetReloaded(AZ::Data::Asset asset) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // AZ::TransformNotificationBus::Handler interface implementation - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // IRenderNode interface implementation - void Render(const struct SRendParams& inRenderParams, const struct SRenderingPassInfo& passInfo) override; - bool GetLodDistances(const SFrameLodInfo& frameLodInfo, float* distances) const override; - float GetFirstLodDistance() const override { return m_lodDistance; } - EERType GetRenderNodeType() override; - bool CanExecuteRenderAsJob() override; - const char* GetName() const override; - const char* GetEntityClassName() const override; - Vec3 GetPos(bool bWorldOnly = true) const override; - const AABB GetBBox() const override; - void SetBBox(const AABB& WSBBox) override; - void OffsetPosition(const Vec3& delta) override; - void SetMaterial(_smart_ptr pMat) override; - _smart_ptr GetMaterial(Vec3* pHitPos = nullptr) override; - _smart_ptr GetMaterialOverride() override; - IStatObj* GetEntityStatObj(unsigned int nPartId = 0, unsigned int nSubPartId = 0, Matrix34A* pMatrix = nullptr, bool bReturnOnlyVisible = false) override; - _smart_ptr GetEntitySlotMaterial(unsigned int nPartId, bool bReturnOnlyVisible = false, bool* pbDrawNear = nullptr) override; - float GetMaxViewDist() override; - void GetMemoryUsage(class ICrySizer* pSizer) const override; - AZ::EntityId GetEntityId() override { return m_renderOptions.m_attachedToEntityId; } - float GetUniformScale() override; - float GetColumnScale(int column) override; - ////////////////////////////////////////////////////////////////////////// - - //! Invoked in the editor when a property requiring render state refresh - //! has changed. - void RefreshRenderState(); - - //! Set/get auxiliary render flags. - void SetAuxiliaryRenderFlags(uint32 flags); - uint32 GetAuxiliaryRenderFlags() const { return m_auxiliaryRenderFlags; } - void UpdateAuxiliaryRenderFlags(bool on, uint32 mask); - - void SetVisible(bool isVisible); - bool GetVisible(); - - static void Reflect(AZ::ReflectContext* context); - - static float GetDefaultMaxViewDist(); - static AZ::Uuid GetRenderOptionsUuid() { return AZ::AzTypeInfo::Uuid(); } - - //! Registers or unregisters our render node with the render. - void RegisterWithRenderer(bool registerWithRenderer); - bool IsRegisteredWithRenderer() const { return m_isRegisteredWithRenderer; } - - //! This function caches off the static flag stat of the transform; - void SetTransformStaticState(bool isStatic); - const AZ::Transform& GetTransform() const; - - void SetContextId(AzFramework::EntityContextId contextId) { m_contextId = contextId; } - - protected: - - //! Calculates base LOD distance based on mesh characteristics. - //! We do this each time the mesh resource changes. - void UpdateLodDistance(const SFrameLodInfo& frameLodInfo); - - //! Computes desired LOD level for the assigned mesh instance. - CLodValue ComputeLOD(int wantedLod, const SRenderingPassInfo& passInfo); - - //! Computes the entity-relative (local space) bounding box for - //! the assigned mesh. - virtual void UpdateLocalBoundingBox(); - - //! Updates the world-space bounding box and world space transform - //! for the assigned mesh. - void UpdateWorldBoundingBox(); - - //! Applies configured render options to the render node. - void ApplyRenderOptions(); - - //! Populates the render mesh from the mesh asset - void BuildRenderMesh(); - - class MeshRenderOptions - { - public: - - AZ_TYPE_INFO(MeshRenderOptions, "{EFF77BEB-CB99-44A3-8F15-111B0200F50D}") - - MeshRenderOptions(); - - float m_opacity; //!< Alpha/opacity value for rendering. - float m_maxViewDist; //!< Maximum draw distance. - float m_viewDistMultiplier; //!< Adjusts max view distance. If 1.0 then default max view distance is used. - AZ::u32 m_lodRatio; //!< Controls LOD distance ratio. - bool m_useVisAreas; //!< Allow VisAreas to control this component's visibility. - bool m_castShadows; //!< Casts shadows. - bool m_lodBoundingBoxBased; //!< LOD based on Bounding Boxes. - bool m_rainOccluder; //!< Occludes raindrops. - bool m_affectNavmesh; //!< Cuts out of the navmesh. - bool m_affectDynamicWater; //!< Affects dynamic water (ripples). - bool m_acceptDecals; //!< Accepts decals. - bool m_receiveWind; //!< Receives wind. - bool m_visibilityOccluder; //!< Appropriate for visibility occluding. - bool m_dynamicMesh; // Mesh can change or deform independent of transform - bool m_hasStaticTransform; - bool m_affectGI; //!< Mesh affects Global Illumination. - - //! The Id of the entity we're associated with, for bus subscription. - //Moved from render mesh to this struct for serialization/reflection utility - AZ::EntityId m_attachedToEntityId; - - AZStd::function m_changeCallback; - - // Minor property changes don't require refreshing/rebuilding the property tree since no other properties - // are shown/hidden as a result of a change. - AZ::u32 OnMinorChanged() - { - if (m_changeCallback) - { - m_changeCallback(); - } - return AZ::Edit::PropertyRefreshLevels::None; - } - - AZ::u32 OnMajorChanged() - { - if (m_changeCallback) - { - m_changeCallback(); - } - return AZ::Edit::PropertyRefreshLevels::EntireTree; - } - - //Returns true if the transform is static and the mesh is not deformable. - bool IsStatic() const; - bool AffectsGi() const; - AZ::Crc32 StaticPropertyVisibility() const; - static void Reflect(AZ::ReflectContext* context); - - private: - static bool VersionConverter(AZ::SerializeContext& context, - AZ::SerializeContext::DataElementNode& classElement); - }; - - //! Should be visible. - bool m_visible; - - //! User-specified material override. - AzFramework::SimpleAssetReference m_material; - - //! Render flags/options. - MeshRenderOptions m_renderOptions; - - //! Currently-assigned material. Null if no material is manually assigned. - MaterialPtr m_materialOverride; - - //! World and render transforms. - //! These are equivalent, but for different math libraries. - AZ::Transform m_worldTransform; - Matrix34 m_renderTransform; - - //! Local and world bounding boxes. - AABB m_localBoundingBox; - AABB m_worldBoundingBox; - - //! Additional render flags -- for special editor behavior, etc. - uint32 m_auxiliaryRenderFlags; - - //! Remember which flags have ever been toggled externally so that we can shut them off - uint32 m_auxiliaryRenderFlagsHistory; - - //! Reference to current asset - AZ::Data::Asset m_meshAsset; - MeshPtr m_statObj; - - //! Computed LOD distance. - float m_lodDistance; - - //! Computed first LOD distance (the following are multiplies of the index) - float m_lodDistanceScaled; - - //! Scale we need to multiply the distance by. - float m_lodDistanceScaleValue; - - //! Identifies whether we've already registered our node with the renderer. - bool m_isRegisteredWithRenderer; - - //! Tracks if the object was moved so we can notify the renderer. - bool m_objectMoved; - - // Helper to store indices for meshes to be modified by other components. - MeshModificationRequestHelper m_modificationHelper; - - // EntityContext of the component - AzFramework::EntityContextId m_contextId; - }; - - - - class MeshComponent - : public AZ::Component - , public MeshComponentRequestBus::Handler - , public MaterialOwnerRequestBus::Handler - , public RenderNodeRequestBus::Handler - , public LegacyMeshComponentRequestBus::Handler - , public AzFramework::BoundsRequestBus::Handler - , public AzFramework::RenderGeometry::IntersectionRequestBus::Handler - { - public: - friend class EditorMeshComponent; - - AZ_COMPONENT(MeshComponent, "{2F4BAD46-C857-4DCB-A454-C412DE67852A}"); - - MeshComponent(); - ~MeshComponent() override; - - AZ_DISABLE_COPY_MOVE(MeshComponent); - - // AZ::Component overrides ... - void Activate() override; - void Deactivate() override; - - // BoundsRequestBus and MeshComponentRequestBus overrides ... - AZ::Aabb GetWorldBounds() override; - AZ::Aabb GetLocalBounds() override; - - // MeshComponentRequestBus overrides ... - void SetMeshAsset(const AZ::Data::AssetId& id) override; - AZ::Data::Asset GetMeshAsset() override { return m_meshRenderNode.GetMeshAsset(); } - void SetVisibility(bool newVisibility) override; - bool GetVisibility() override; - - // MaterialOwnerRequestBus overrides ... - bool IsMaterialOwnerReady() override; - void SetMaterial(_smart_ptr) override; - _smart_ptr GetMaterial() override; - void SetMaterialHandle(const MaterialHandle& materialHandle) override; - MaterialHandle GetMaterialHandle() override; - void SetMaterialParamVector4(const AZStd::string& /*name*/, const AZ::Vector4& /*value*/, int /*materialId = 1*/) override; - void SetMaterialParamVector3(const AZStd::string& /*name*/, const AZ::Vector3& /*value*/, int /*materialId = 1*/) override; - void SetMaterialParamColor(const AZStd::string& /*name*/, const AZ::Color& /*value*/, int /*materialId = 1*/) override; - void SetMaterialParamFloat(const AZStd::string& /*name*/, float /*value*/, int /*materialId = 1*/) override; - AZ::Vector4 GetMaterialParamVector4(const AZStd::string& /*name*/, int /*materialId = 1*/) override; - AZ::Vector3 GetMaterialParamVector3(const AZStd::string& /*name*/, int /*materialId = 1*/) override; - AZ::Color GetMaterialParamColor(const AZStd::string& /*name*/, int /*materialId = 1*/) override; - float GetMaterialParamFloat(const AZStd::string& /*name*/, int /*materialId = 1*/) override; - - // RenderNodeRequestBus overrides ... - IRenderNode* GetRenderNode() override; - float GetRenderNodeRequestBusOrder() const override; - static const float s_renderNodeRequestBusOrder; - - // MeshComponentRequestBus overrides ... - IStatObj* GetStatObj() override; - - // IntersectionRequestBus overrides ... - AzFramework::RenderGeometry::RayResult RenderGeometryIntersect(const AzFramework::RenderGeometry::RayRequest& ray) override; - - protected: - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("MeshService", 0x71d8a455)); - provided.push_back(AZ_CRC("LegacyMeshService", 0xb462a299)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("MeshService", 0x71d8a455)); - incompatible.push_back(AZ_CRC("LegacyMeshService", 0xb462a299)); - } - - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - static void Reflect(AZ::ReflectContext* context); - - void RequireSendingRenderMeshForEditing(size_t lodIndex, size_t primitiveIndex); - void NoRenderMeshesForEditing(); - - ////////////////////////////////////////////////////////////////////////// - // Reflected Data - MeshComponentRenderNode m_meshRenderNode; - MaterialOwnerRequestBusHandlerImpl* m_materialBusHandler; - }; - -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/Tests/EditorMeshComponentTests.cpp b/Gems/LmbrCentral/Code/Tests/EditorMeshComponentTests.cpp deleted file mode 100644 index 8586955254..0000000000 --- a/Gems/LmbrCentral/Code/Tests/EditorMeshComponentTests.cpp +++ /dev/null @@ -1,293 +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 "LmbrCentral_precompiled.h" - -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "Source/Rendering/EditorMeshComponent.h" - -namespace UnitTest -{ - // base physical entity which can be derived from to detect other specific use-cases - struct PhysicalEntityPlaceHolder - : public IPhysicalEntity - { - pe_type GetType() const override { return PE_NONE; } - int AddRef() override { return 0; } - int Release() override { return 0; } - int SetParams([[maybe_unused]] const pe_params* params, [[maybe_unused]] int bThreadSafe = 0) override { return 0; } - int GetParams([[maybe_unused]] pe_params* params) const override { return 0; } - int GetStatus([[maybe_unused]] pe_status* status) const override { return 0; } - int Action(const pe_action*, [[maybe_unused]] int bThreadSafe = 0) override { return 0; } - int AddGeometry([[maybe_unused]] phys_geometry* pgeom, [[maybe_unused]] pe_geomparams* params, [[maybe_unused]] int id = -1, [[maybe_unused]] int bThreadSafe = 0) override { return 0; } - void RemoveGeometry([[maybe_unused]] int id, [[maybe_unused]] int bThreadSafe = 0) override {} - PhysicsForeignData GetForeignData([[maybe_unused]] int itype = 0) const override { return PhysicsForeignData{}; } - int GetiForeignData() const override { return 0; } - int GetStateSnapshot([[maybe_unused]] class CStream& stm, [[maybe_unused]] float time_back = 0, [[maybe_unused]] int flags = 0) override { return 0; } - int GetStateSnapshot([[maybe_unused]] TSerialize ser, [[maybe_unused]] float time_back = 0, [[maybe_unused]] int flags = 0) override { return 0; } - int SetStateFromSnapshot([[maybe_unused]] class CStream& stm, [[maybe_unused]] int flags = 0) override { return 0; } - int PostSetStateFromSnapshot() override { return 0; } - unsigned int GetStateChecksum() override { return 0; } - void SetNetworkAuthority([[maybe_unused]] int authoritive = -1, [[maybe_unused]] int paused = -1) override {} - int SetStateFromSnapshot([[maybe_unused]] TSerialize ser, [[maybe_unused]] int flags = 0) override { return 0; } - int SetStateFromTypedSnapshot([[maybe_unused]] TSerialize ser, [[maybe_unused]] int type, [[maybe_unused]] int flags = 0) override { return 0; } - int GetStateSnapshotTxt([[maybe_unused]] char* txtbuf, [[maybe_unused]] int szbuf, [[maybe_unused]] float time_back = 0) override { return 0; } - void SetStateFromSnapshotTxt([[maybe_unused]] const char* txtbuf, [[maybe_unused]] int szbuf) override {} - int DoStep([[maybe_unused]] float time_interval) override { return 0; } - int DoStep([[maybe_unused]] float time_interval, [[maybe_unused]] int iCaller) override { return 0; } - void StartStep([[maybe_unused]] float time_interval) override {} - void StepBack([[maybe_unused]] float time_interval) override {} - void GetMemoryStatistics([[maybe_unused]] ICrySizer* pSizer) const override {} - }; - - // special test fake to validate incoming pe_params - struct PhysicalEntitySetParamsCheck - : public PhysicalEntityPlaceHolder - { - int SetParams(const pe_params* params, [[maybe_unused]] int bThreadSafe = 0) override - { - if (params->type == pe_params_pos::type_id) - { - pe_params_pos* params_pos = (pe_params_pos*)params; - - Vec3 s; - if (Matrix34* m34 = params_pos->pMtx3x4) - { - s.Set(m34->GetColumn(0).len(), m34->GetColumn(1).len(), m34->GetColumn(2).len()); - Matrix33 m33(m34->GetColumn(0) / s.x, m34->GetColumn(1) / s.y, m34->GetColumn(2) / s.z); - // ensure passed in params_pos->pMtx3x4 is orthonormal - // ref - see Cry_Quat.h - explicit ILINE Quat_tpl(const Matrix33_tpl&m) - m_isOrthonormal = m33.IsOrthonormalRH(0.1f); - } - } - - return 0; - } - - bool m_isOrthonormal = false; - }; - - class TestEditorMeshComponent - : public LmbrCentral::EditorMeshComponent - { - public: - AZ_EDITOR_COMPONENT(TestEditorMeshComponent, "{6C6B593A-1946-4239-AE16-E8B96D9835E5}", LmbrCentral::EditorMeshComponent) - - static void Reflect(AZ::ReflectContext* context); - - TestEditorMeshComponent() = default; - - }; - - void TestEditorMeshComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(0); - } - } - - class EditorMeshComponentTestFixture - : public ToolsApplicationFixture - { - AZStd::unique_ptr m_testMeshComponentDescriptor; - - public: - void SetUpEditorFixtureImpl() override - { - AZ::SerializeContext* serializeContext = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); - - m_testMeshComponentDescriptor = - AZStd::unique_ptr(TestEditorMeshComponent::CreateDescriptor()); - m_testMeshComponentDescriptor->Reflect(serializeContext); - } - - void TearDownEditorFixtureImpl() override - { - m_testMeshComponentDescriptor.reset(); - } - }; - - struct MeshAssetHandlerFixture - : ScopedAllocatorSetupFixture - { - protected: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - AZ::Data::AssetManager::Create(AZ::Data::AssetManager::Descriptor()); - AZ::Data::AssetManager::Instance().SetAssetInfoUpgradingEnabled(false); - - m_handler.Register(); - } - - void TearDown() override - { - m_handler.Unregister(); - AZ::Data::AssetManager::Destroy(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - - LmbrCentral::MeshAssetHandler m_handler; - }; - - struct MockAssetSystemRequestHandler - : AzFramework::AssetSystemRequestBus::Handler - { - MockAssetSystemRequestHandler() - { - BusConnect(); - } - - ~MockAssetSystemRequestHandler() - { - BusDisconnect(); - } - - AzFramework::AssetSystem::AssetStatus GetAssetStatusById([[maybe_unused]] const AZ::Data::AssetId& assetId) override - { - m_statusRequest = true; - - return AzFramework::AssetSystem::AssetStatus_Queued; - } - - MOCK_METHOD1(CompileAssetSync, AzFramework::AssetSystem::AssetStatus (const AZStd::string&)); - MOCK_METHOD1(CompileAssetSync_FlushIO, AzFramework::AssetSystem::AssetStatus (const AZStd::string&)); - MOCK_METHOD1(CompileAssetSyncById, AzFramework::AssetSystem::AssetStatus (const AZ::Data::AssetId&)); - MOCK_METHOD1(CompileAssetSyncById_FlushIO, AzFramework::AssetSystem::AssetStatus (const AZ::Data::AssetId&)); - MOCK_METHOD4(ConfigureSocketConnection, bool (const AZStd::string&, const AZStd::string&, const AZStd::string&, const AZStd::string&)); - MOCK_METHOD1(Connect, bool (const char*)); - MOCK_METHOD2(ConnectWithTimeout, bool (const char*, AZStd::chrono::duration)); - MOCK_METHOD0(Disconnect, bool ()); - MOCK_METHOD1(EscalateAssetBySearchTerm, bool (AZStd::string_view)); - MOCK_METHOD1(EscalateAssetByUuid, bool (const AZ::Uuid&)); - MOCK_METHOD0(GetAssetProcessorPingTimeMilliseconds, float ()); - MOCK_METHOD1(GetAssetStatus, AzFramework::AssetSystem::AssetStatus (const AZStd::string&)); - MOCK_METHOD1(GetAssetStatus_FlushIO, AzFramework::AssetSystem::AssetStatus (const AZStd::string&)); - MOCK_METHOD2(GetAssetStatusSearchType, AzFramework::AssetSystem::AssetStatus(const AZStd::string&, int)); - MOCK_METHOD2(GetAssetStatusSearchType_FlushIO, AzFramework::AssetSystem::AssetStatus(const AZStd::string&, int)); - MOCK_METHOD1(GetAssetStatusById_FlushIO, AzFramework::AssetSystem::AssetStatus (const AZ::Data::AssetId&)); - MOCK_METHOD3(GetUnresolvedProductReferences, void (AZ::Data::AssetId, AZ::u32&, AZ::u32&)); - MOCK_METHOD0(SaveCatalog, bool ()); - MOCK_METHOD1(SetAssetProcessorIP, void (const AZStd::string&)); - MOCK_METHOD1(SetAssetProcessorPort, void (AZ::u16)); - MOCK_METHOD1(SetBranchToken, void (const AZStd::string&)); - MOCK_METHOD1(SetProjectName, void (const AZStd::string&)); - MOCK_METHOD0(ShowAssetProcessor, void ()); - MOCK_METHOD1(ShowInAssetProcessor, void (const AZStd::string&)); - MOCK_METHOD1(WaitUntilAssetProcessorReady, bool(AZStd::chrono::duration)); - MOCK_METHOD1(WaitUntilAssetProcessorConnected, bool(AZStd::chrono::duration)); - MOCK_METHOD1(WaitUntilAssetProcessorDisconnected, bool(AZStd::chrono::duration)); - MOCK_METHOD0(AssetProcessorIsReady, bool()); - MOCK_METHOD0(ConnectedWithAssetProcessor, bool()); - MOCK_METHOD0(DisconnectedWithAssetProcessor, bool()); - MOCK_METHOD0(NegotiationWithAssetProcessorFailed, bool()); - MOCK_METHOD0(StartDisconnectingAssetProcessor, void()); - MOCK_METHOD1(EstablishAssetProcessorConnection, bool(const AzFramework::AssetSystem::ConnectionSettings&)); - MOCK_METHOD3(AppendAssetToPrioritySet, bool (const AZStd::string&, const AZ::Uuid&, uint32_t)); - MOCK_METHOD3(AppendAssetsToPrioritySet, bool (const AZStd::string&, const AZStd::vector&, uint32_t)); - MOCK_METHOD2(RemoveAssetFromPrioritySet, bool (const AZStd::string&, const AZ::Uuid&)); - MOCK_METHOD2(RemoveAssetsFromPrioritySet, bool (const AZStd::string&, const AZStd::vector&)); - bool m_statusRequest = false; - }; - - struct MockCatalog - : AZ::Data::AssetCatalogRequestBus::Handler - { - MockCatalog() - { - BusConnect(); - } - - ~MockCatalog() - { - BusDisconnect(); - } - - AZ::Data::AssetId GetAssetIdByPath(const char*, const AZ::Data::AssetType&, bool) override - { - m_generatedId = AZ::Data::AssetId(AZ::Uuid::CreateRandom(), 1234); - - return m_generatedId; - } - - MOCK_METHOD1(GetAssetInfoById, AZ::Data::AssetInfo (const AZ::Data::AssetId&)); - MOCK_METHOD1(AddAssetType, void (const AZ::Data::AssetType&)); - MOCK_METHOD1(AddDeltaCatalog, bool (AZStd::shared_ptr)); - MOCK_METHOD1(AddExtension, void (const char*)); - MOCK_METHOD0(ClearCatalog, void ()); - MOCK_METHOD5(CreateBundleManifest, bool (const AZStd::string&, const AZStd::vector&, const AZStd::string&, int, const AZStd::vector&)); - MOCK_METHOD2(CreateDeltaCatalog, bool (const AZStd::vector&, const AZStd::string&)); - MOCK_METHOD0(DisableCatalog, void ()); - MOCK_METHOD1(EnableCatalogForAsset, void (const AZ::Data::AssetType&)); - MOCK_METHOD3(EnumerateAssets, void (BeginAssetEnumerationCB, AssetEnumerationCB, EndAssetEnumerationCB)); - MOCK_METHOD1(GenerateAssetIdTEMP, AZ::Data::AssetId (const char*)); - MOCK_METHOD1(GetAllProductDependencies, AZ::Outcome, AZStd::string> (const AZ::Data::AssetId&)); - MOCK_METHOD3(GetAllProductDependenciesFilter, AZ::Outcome, AZStd::string> (const AZ::Data::AssetId&, const AZStd::unordered_set&, const AZStd::vector&)); - MOCK_METHOD1(GetAssetPathById, AZStd::string (const AZ::Data::AssetId&)); - MOCK_METHOD1(GetDirectProductDependencies, AZ::Outcome, AZStd::string> (const AZ::Data::AssetId&)); - MOCK_METHOD1(GetHandledAssetTypes, void (AZStd::vector&)); - MOCK_METHOD0(GetRegisteredAssetPaths, AZStd::vector ()); - MOCK_METHOD2(InsertDeltaCatalog, bool (AZStd::shared_ptr, size_t)); - MOCK_METHOD2(InsertDeltaCatalogBefore, bool (AZStd::shared_ptr, AZStd::shared_ptr)); - MOCK_METHOD1(LoadCatalog, bool (const char*)); - MOCK_METHOD2(RegisterAsset, void (const AZ::Data::AssetId&, AZ::Data::AssetInfo&)); - MOCK_METHOD1(RemoveDeltaCatalog, bool (AZStd::shared_ptr)); - MOCK_METHOD1(SaveCatalog, bool (const char*)); - MOCK_METHOD0(StartMonitoringAssets, void ()); - MOCK_METHOD0(StopMonitoringAssets, void ()); - MOCK_METHOD1(UnregisterAsset, void (const AZ::Data::AssetId&)); - - AZ::Data::AssetId m_generatedId{}; - }; - - struct MockAssetData - : LmbrCentral::MeshAsset - { - MockAssetData(AZ::Data::AssetId assetId) - { - m_assetId = assetId; - } - }; - - TEST_F(MeshAssetHandlerFixture, LoadAsset_StillInQueue_LoadsSubstituteAsset) - { - MockAssetSystemRequestHandler assetSystem; - MockCatalog catalog; - AZ::Data::AssetId assetId(AZ::Uuid::CreateRandom(), 0); - - AZ::Data::Asset asset(aznew MockAssetData(assetId), AZ::Data::AssetLoadBehavior::Default); - auto substituteAssetId = m_handler.AssetMissingInCatalog(asset); - - ASSERT_TRUE(assetSystem.m_statusRequest); - ASSERT_TRUE(catalog.m_generatedId.IsValid()); - ASSERT_EQ(substituteAssetId, catalog.m_generatedId); - } - - - -} // namespace UnitTest diff --git a/Gems/LmbrCentral/Code/include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h b/Gems/LmbrCentral/Code/include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h new file mode 100644 index 0000000000..b24ac2709b --- /dev/null +++ b/Gems/LmbrCentral/Code/include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h @@ -0,0 +1,54 @@ +/* +* 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 + +namespace LmbrCentral +{ + /*! + * SkeletonHierarchyRequestBus + * Messages serviced by components to provide information about skeletal hierarchies. + */ + class SkeletalHierarchyRequests + : public AZ::ComponentBus + { + public: + + /** + * \return Number of joints in the skeleton joint hierarchy. + */ + virtual AZ::u32 GetJointCount() { return 0; } + + /** + * \param jointIndex Index of joint whose name should be returned. + * \return Name of the joint at the specified index. Null if joint index is not valid. + */ + virtual const char* GetJointNameByIndex(AZ::u32 /*jointIndex*/) { return nullptr; } + + /** + * \param jointName Name of joint whose index should be returned. + * \return Index of the joint with the specified name. -1 if the joint was not found. + */ + virtual AZ::s32 GetJointIndexByName(const char* /*jointName*/) { return 0; } + + /** + * \param jointIndex Index of joint whose local-space transform should be returned. + * \return Joint's character-space transform. Identify if joint index was not valid. + */ + virtual AZ::Transform GetJointTransformCharacterRelative(AZ::u32 /*jointIndex*/) { return AZ::Transform::CreateIdentity(); } + }; + + using SkeletalHierarchyRequestBus = AZ::EBus; + +} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/EditorMeshBus.h b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/EditorMeshBus.h deleted file mode 100644 index 19cad8cd29..0000000000 --- a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/EditorMeshBus.h +++ /dev/null @@ -1,28 +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 - -namespace LmbrCentral -{ - class EditorMeshBusRequests : - public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual bool AddMeshComponentWithAssetId(const AZ::EntityId& targetEntity, const AZ::Uuid& meshAssetId) = 0; - }; - using EditorMeshBus = AZ::EBus; -} diff --git a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MeshComponentBus.h b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MeshComponentBus.h deleted file mode 100644 index 2f64bb084a..0000000000 --- a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/MeshComponentBus.h +++ /dev/null @@ -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. -* -*/ -#pragma once - -#include -#include -#include -#include - -struct IStatObj; -struct SRenderingPassInfo; -struct SRendParams; - -namespace LmbrCentral -{ - /*! - * MeshComponentRequestBus - * Messages serviced by the mesh component. - */ - class MeshComponentRequests - : public AZ::ComponentBus - { - public: - - /** - * Returns the axis aligned bounding box in world coordinates - */ - virtual AZ::Aabb GetWorldBounds() = 0; - - /** - * Returns the axis aligned bounding box in model coordinates - */ - virtual AZ::Aabb GetLocalBounds() = 0; - - /** - * Sets the mesh asset for this component - */ - virtual void SetMeshAsset(const AZ::Data::AssetId& id) = 0; - - /** - * Returns the asset used by the mesh - */ - virtual AZ::Data::Asset GetMeshAsset() = 0; - - /** - * Returns true if the mesh is currently visible - */ - virtual bool GetVisibility() { return true; } - - /** - * Sets the current visibility of the mesh - */ - virtual void SetVisibility([[maybe_unused]] bool isVisible) {} - }; - - using MeshComponentRequestBus = AZ::EBus; - - /*! - * SkeletonHierarchyRequestBus - * Messages serviced by components to provide information about skeletal hierarchies. - */ - class SkeletalHierarchyRequests - : public AZ::ComponentBus - { - public: - - /** - * \return Number of joints in the skeleton joint hierarchy. - */ - virtual AZ::u32 GetJointCount() { return 0; } - - /** - * \param jointIndex Index of joint whose name should be returned. - * \return Name of the joint at the specified index. Null if joint index is not valid. - */ - virtual const char* GetJointNameByIndex(AZ::u32 /*jointIndex*/) { return nullptr; } - - /** - * \param jointName Name of joint whose index should be returned. - * \return Index of the joint with the specified name. -1 if the joint was not found. - */ - virtual AZ::s32 GetJointIndexByName(const char* /*jointName*/) { return 0; } - - /** - * \param jointIndex Index of joint whose local-space transform should be returned. - * \return Joint's character-space transform. Identify if joint index was not valid. - */ - virtual AZ::Transform GetJointTransformCharacterRelative(AZ::u32 /*jointIndex*/) { return AZ::Transform::CreateIdentity(); } - }; - - using SkeletalHierarchyRequestBus = AZ::EBus; - - /*! - * LegacyMeshComponentRequestBus - * Messages serviced by the mesh component. - */ - class LegacyMeshComponentRequests - : public AZ::ComponentBus - { - public: - virtual IStatObj* GetStatObj() = 0; - }; - - using LegacyMeshComponentRequestBus = AZ::EBus; - - /*! - * MeshComponentNotificationBus - * Events dispatched by the mesh component. - */ - class MeshComponentNotifications - : public AZ::ComponentBus - { - public: - - /** - * Notifies listeners the mesh instance has been created. - * \param asset - The asset the mesh instance is based on. - */ - virtual void OnMeshCreated(const AZ::Data::Asset& asset) { (void)asset; } - - /** - * Notifies listeners that the mesh instance has been destroyed. - */ - virtual void OnMeshDestroyed() {} - - virtual void OnBoundsReset() {}; - - /* - * Notifies listeners prior to making the render call - */ - virtual void OnMeshPreRender([[maybe_unused]] const struct SRendParams& inOutRenderParams, [[maybe_unused]] const SRenderingPassInfo& passInfo) {}; - - /** - * When connecting to this bus if the asset is ready you will immediately get an OnMeshCreated event - **/ - template - struct ConnectionPolicy - : public AZ::EBusConnectionPolicy - { - static void Connect(typename Bus::BusPtr& busPtr, typename Bus::Context& context, typename Bus::HandlerNode& handler, typename Bus::Context::ConnectLockGuard& connectLock, const typename Bus::BusIdType& id = 0) - { - AZ::EBusConnectionPolicy::Connect(busPtr, context, handler, connectLock, id); - - AZ::Data::Asset asset; - EBUS_EVENT_ID_RESULT(asset, id, MeshComponentRequestBus, GetMeshAsset); - if (asset.GetStatus() == AZ::Data::AssetData::AssetStatus::Ready) - { - handler->OnMeshCreated(asset); - } - } - }; - }; - - using MeshComponentNotificationBus = AZ::EBus; -} // namespace LmbrCentral diff --git a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/Utils/MaterialOwnerRequestBusHandlerImpl.h b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/Utils/MaterialOwnerRequestBusHandlerImpl.h index 2779f68eb4..6fc0e85553 100644 --- a/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/Utils/MaterialOwnerRequestBusHandlerImpl.h +++ b/Gems/LmbrCentral/Code/include/LmbrCentral/Rendering/Utils/MaterialOwnerRequestBusHandlerImpl.h @@ -12,7 +12,6 @@ #pragma once #include -#include #include #include @@ -28,8 +27,7 @@ namespace LmbrCentral //! This does not actually inherit the MaterialOwnerRequestBus::Handler interface because it is //! not intended to subscribe to that bus, but it does provide implementations for all the same functions. class MaterialOwnerRequestBusHandlerImpl - : public MeshComponentNotificationBus::Handler - , public AZ::TickBus::Handler + : public AZ::TickBus::Handler , public MaterialOwnerRequestBus::Handler { using MaterialPtr = _smart_ptr < IMaterial >; @@ -57,14 +55,7 @@ namespace LmbrCentral if (m_renderNode) { - if (!m_renderNode->IsReady()) - { - // Some material owners, in particular MeshComponents, may not be ready upon activation because the - // actual mesh data and default material haven't been loaded yet. Until the RenderNode is ready, - // it's material probably isn't valid. - MeshComponentNotificationBus::Handler::BusConnect(entityId); - } - else + if (m_renderNode->IsReady()) { // For some material owner types (like DecalComponent), the material is ready immediately. But we can't // send the event yet because components are still being Activated, so we delay until the first tick. @@ -81,7 +72,6 @@ namespace LmbrCentral void Deactivate() { m_notificationBus = nullptr; - MeshComponentNotificationBus::Handler::BusDisconnect(); MaterialOwnerRequestBus::Handler::BusDisconnect(); AZ::TickBus::Handler::BusDisconnect(); } @@ -300,16 +290,6 @@ namespace LmbrCentral } ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // MeshComponentNotificationBus interface implementation - void OnMeshCreated([[maybe_unused]] const AZ::Data::Asset& asset) override - { - AZ_Assert(IsMaterialOwnerReady(), "Got OnMeshCreated but the RenderNode still isn't ready"); - SendReadyEvent(); - MeshComponentNotificationBus::Handler::BusDisconnect(); - } - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // TickBus interface implementation void OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) override diff --git a/Gems/LmbrCentral/Code/lmbrcentral_editor_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_editor_files.cmake index 8d9e70478a..be62919093 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_editor_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_editor_files.cmake @@ -12,14 +12,11 @@ set(FILES include/LmbrCentral/Rendering/EditorCameraCorrectionBus.h include/LmbrCentral/Rendering/EditorLightComponentBus.h - include/LmbrCentral/Rendering/EditorMeshBus.h include/LmbrCentral/Shape/EditorPolygonPrismShapeComponentBus.h include/LmbrCentral/Shape/EditorSplineComponentBus.h include/LmbrCentral/Shape/EditorTubeShapeComponentBus.h include/LmbrCentral/Component/EditorWrappedComponentBase.h include/LmbrCentral/Component/EditorWrappedComponentBase.inl - Source/Animation/EditorAttachmentComponent.h - Source/Animation/EditorAttachmentComponent.cpp Source/Audio/EditorAudioAreaEnvironmentComponent.h Source/Audio/EditorAudioAreaEnvironmentComponent.cpp Source/Audio/EditorAudioEnvironmentComponent.h @@ -40,8 +37,6 @@ set(FILES Source/Builders/BenchmarkAssetBuilder/BenchmarkAssetBuilderComponent.cpp Source/Builders/BenchmarkAssetBuilder/BenchmarkAssetBuilderWorker.h Source/Builders/BenchmarkAssetBuilder/BenchmarkAssetBuilderWorker.cpp - Source/Rendering/EditorMeshComponent.h - Source/Rendering/EditorMeshComponent.cpp Source/Scripting/EditorLookAtComponent.h Source/Scripting/EditorLookAtComponent.cpp Source/Scripting/EditorRandomTimedSpawnerComponent.cpp diff --git a/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake index a96f0ac4ab..b78ff769c2 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_editor_tests_files.cmake @@ -19,7 +19,6 @@ set(FILES Tests/EditorCompoundShapeComponentTests.cpp Tests/EditorCylinderShapeComponentTests.cpp Tests/EditorPolygonPrismShapeComponentTests.cpp - Tests/EditorMeshComponentTests.cpp Tests/SpawnerComponentTest.cpp Tests/Builders/CopyDependencyBuilderTest.cpp Tests/Builders/SliceBuilderTests.cpp diff --git a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake index 99d1adda14..df6bafd499 100644 --- a/Gems/LmbrCentral/Code/lmbrcentral_files.cmake +++ b/Gems/LmbrCentral/Code/lmbrcentral_files.cmake @@ -17,6 +17,7 @@ set(FILES include/LmbrCentral/Ai/NavigationSystemBus.h include/LmbrCentral/Ai/NavigationSeedBus.h include/LmbrCentral/Animation/AttachmentComponentBus.h + include/LmbrCentral/Animation/SkeletalHierarchyRequestBus.h include/LmbrCentral/Audio/AudioEnvironmentComponentBus.h include/LmbrCentral/Audio/AudioListenerComponentBus.h include/LmbrCentral/Audio/AudioMultiPositionComponentBus.h @@ -40,7 +41,6 @@ set(FILES include/LmbrCentral/Rendering/MaterialHandle.h include/LmbrCentral/Rendering/MaterialOwnerBus.h include/LmbrCentral/Rendering/MeshAsset.h - include/LmbrCentral/Rendering/MeshComponentBus.h include/LmbrCentral/Rendering/MeshModificationBus.h include/LmbrCentral/Rendering/RenderNodeBus.h include/LmbrCentral/Rendering/GiRegistrationBus.h @@ -69,8 +69,6 @@ set(FILES include/LmbrCentral/Terrain/TerrainSystemRequestBus.h Source/Ai/NavigationSystemComponent.h Source/Ai/NavigationSystemComponent.cpp - Source/Animation/AttachmentComponent.h - Source/Animation/AttachmentComponent.cpp Source/Audio/AudioAreaEnvironmentComponent.h Source/Audio/AudioAreaEnvironmentComponent.cpp Source/Audio/AudioEnvironmentComponent.h @@ -99,11 +97,6 @@ set(FILES Source/Events/ReflectScriptableEvents.cpp Source/Geometry/GeometrySystemComponent.h Source/Geometry/GeometrySystemComponent.cpp - Source/Rendering/MaterialHandle.cpp - Source/Rendering/MeshAssetHandler.h - Source/Rendering/MeshAssetHandler.cpp - Source/Rendering/MeshComponent.h - Source/Rendering/MeshComponent.cpp Source/Rendering/EntityDebugDisplayComponent.h Source/Rendering/EntityDebugDisplayComponent.cpp Source/Scripting/LookAtComponent.h diff --git a/Gems/LyShine/Assets/Textures/Basic/Button_Sliced_Normal.tif b/Gems/LyShine/Assets/Textures/Basic/Button_Sliced_Normal.tif deleted file mode 100644 index c51e06aa9a..0000000000 --- a/Gems/LyShine/Assets/Textures/Basic/Button_Sliced_Normal.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e6a98954dd2b2da87309cf522959efc601444080cf99b850ad64f2b7c5e8668 -size 38228 diff --git a/Gems/LyShine/Assets/Textures/Basic/button_sliced_normal.sprite b/Gems/LyShine/Assets/Textures/Basic/button_sliced_normal.sprite deleted file mode 100644 index 3f6cfe0345..0000000000 --- a/Gems/LyShine/Assets/Textures/Basic/button_sliced_normal.sprite +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f91c1587e5d611d253528c82c93b83e460f7ea71412d2489ff368eca4d8798db -size 122 diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.cpp index a65e220cbd..225f4e0b1a 100644 --- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.cpp +++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewSequenceManager.cpp @@ -16,7 +16,6 @@ #include "UiEditorDLLBus.h" #include "UiAnimViewSequenceManager.h" #include "UiAnimViewUndo.h" -#include "Material/MaterialManager.h" #include "AnimationContext.h" #include "GameEngine.h" #include diff --git a/Gems/LyShine/Code/Source/LyShine.cpp b/Gems/LyShine/Code/Source/LyShine.cpp index 286e756ffa..3ea451b7c5 100644 --- a/Gems/LyShine/Code/Source/LyShine.cpp +++ b/Gems/LyShine/Code/Source/LyShine.cpp @@ -72,6 +72,8 @@ #include #include +#include + #include "Animation/UiAnimationSystem.h" #include "World/UiCanvasAssetRefComponent.h" #include "World/UiCanvasProxyRefComponent.h" @@ -425,11 +427,8 @@ void CLyShine::Render() { FRAME_PROFILER(__FUNCTION__, gEnv->pSystem, PROFILE_UI); - // LYSHINE_ATOM_TODO - convert to use Atom interface to check for null renderer - if (!gEnv || !gEnv->pRenderer || gEnv->pRenderer->GetRenderType() == ERenderType::eRT_Null) + if (AZ::RHI::IsNullRenderer()) { - // if the renderer is not initialized or it is the null renderer (e.g. running as a server) - // then do nothing return; } diff --git a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp index 2af773734c..8578e6b8eb 100644 --- a/Gems/LyShine/Code/Source/UiCanvasComponent.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasComponent.cpp @@ -257,13 +257,13 @@ namespace UiRenderer* GetUiRendererForGame() { CLyShine* lyShine = static_cast(gEnv->pLyShine); - return lyShine->GetUiRenderer(); + return lyShine ? lyShine->GetUiRenderer() : nullptr; } UiRenderer* GetUiRendererForEditor() { CLyShine* lyShine = static_cast(gEnv->pLyShine); - return lyShine->GetUiRendererForEditor(); + return lyShine ? lyShine->GetUiRendererForEditor() : nullptr; } bool IsValidInteractable(const AZ::EntityId& entityId) @@ -4255,8 +4255,8 @@ UiCanvasComponent* UiCanvasComponent::FixupPostLoad(AZ::Entity* canvasEntity, AZ // Initialize the target canvas size and uniform scale // This should be done before calling InGamePostActivate so that the // canvas space rects of the elements are accurate - AZ_Assert(gEnv->pRenderer, "Attempting to access IRenderer before it has been initialized"); - if (gEnv->pRenderer) + UiRenderer* uiRenderer = forEditor ? GetUiRendererForEditor() : GetUiRendererForGame(); + if (uiRenderer) // can be null in automated testing { AZ::Vector2 targetCanvasSize; if (canvasSize) @@ -4265,8 +4265,7 @@ UiCanvasComponent* UiCanvasComponent::FixupPostLoad(AZ::Entity* canvasEntity, AZ } else { - targetCanvasSize.SetX(static_cast(gEnv->pRenderer->GetOverlayWidth())); - targetCanvasSize.SetY(static_cast(gEnv->pRenderer->GetOverlayHeight())); + targetCanvasSize = uiRenderer->GetViewportSize(); } canvasComponent->SetTargetCanvasSizeAndUniformScale(!forEditor, targetCanvasSize); } diff --git a/Gems/LyShine/Code/Source/UiCanvasManager.cpp b/Gems/LyShine/Code/Source/UiCanvasManager.cpp index 6575a1d2f0..958dba0ab8 100644 --- a/Gems/LyShine/Code/Source/UiCanvasManager.cpp +++ b/Gems/LyShine/Code/Source/UiCanvasManager.cpp @@ -612,10 +612,12 @@ void UiCanvasManager::RenderLoadedCanvases() m_fontTextureHasChanged = false; } +#ifdef LYSHINE_ATOM_TODO // render target conversion to Atom // clear the stencil buffer before rendering the loaded canvases - required for masking // NOTE: We want to use ClearTargetsImmediately instead of ClearTargetsLater since we will not be setting the render target ColorF viewportBackgroundColor(0, 0, 0, 0); // if clearing color we want to set alpha to zero also gEnv->pRenderer->ClearTargetsImmediately(FRT_CLEAR_STENCIL, viewportBackgroundColor); +#endif for (auto canvas : m_loadedCanvases) { diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleFrame.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleFrame.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleFrame.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleGradient.png.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleGradient.png.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/CircleGradient.png.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/Circle_Shadow.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/Circle_Shadow.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/Circle_Shadow.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTest.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTest.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTest.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTestPow2.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTestPow2.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ColorTestPow2.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ParticleGlow.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ParticleGlow.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/ParticleGlow.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/button.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/button.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/button.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonPressed.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonPressed.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonPressed.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonSlider.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonSlider.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/buttonSlider.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkbox_spritesheet.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkbox_spritesheet.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkbox_spritesheet.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkered3.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkered3.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/checkered3.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/empty_icon.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/empty_icon.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/empty_icon.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/fixed_image.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/fixed_image.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/fixed_image.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/flipbook_walking.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/flipbook_walking.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/flipbook_walking.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/mask.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/mask.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/mask.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outline.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outline.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outline.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outlineRounded.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outlineRounded.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/outlineRounded.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/panelBkgd.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/panelBkgd.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/panelBkgd.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02_big.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02_big.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02_big.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical_big.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical_big.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern02vertical_big.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03_big.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03_big.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/pattern03_big.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_1.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_1.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_1.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_10.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_10.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_10.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_2.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_2.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_2.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_3.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_3.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_3.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_4.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_4.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_4.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_5.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_5.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_5.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_6.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_6.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_6.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_7.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_7.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_7.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_8.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_8.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_8.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_9.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_9.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_icon_9.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_map.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_map.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/scroll_box_map.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/selected.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/selected.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/selected.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInside2.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInside2.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInside2.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInsideSquare.tif.assetinfo b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInsideSquare.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/shadowInsideSquare.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp b/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp index 516b958adb..05ac4b1363 100644 --- a/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp +++ b/Gems/PhysX/Code/Editor/Source/Components/EditorSystemComponent.cpp @@ -48,11 +48,6 @@ namespace PhysX AzToolsFramework::EditorRequests::Bus::BroadcastResult(editor, &AzToolsFramework::EditorRequests::GetEditor); ISurfaceTypeEnumerator* surfaceTypeEnumerator = nullptr; - if (editor) - { - surfaceTypeEnumerator = editor->Get3DEngine()->GetMaterialManager()->GetSurfaceTypeManager()->GetEnumerator(); - } - if (surfaceTypeEnumerator) { // Enumerate through CryEngine surface types and create a Physics API material for each of them diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp index e1ea3addec..2dc8fc97ec 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.cpp @@ -345,7 +345,6 @@ namespace PhysX AzToolsFramework::BoxManipulatorRequestBus::Handler::BusConnect( AZ::EntityComponentIdPair(GetEntityId(), GetId())); ColliderShapeRequestBus::Handler::BusConnect(GetEntityId()); - LmbrCentral::MeshComponentNotificationBus::Handler::BusConnect(GetEntityId()); AZ::Render::MeshComponentNotificationBus::Handler::BusConnect(GetEntityId()); EditorColliderComponentRequestBus::Handler::BusConnect(AZ::EntityComponentIdPair(GetEntityId(), GetId())); m_nonUniformScaleChangedHandler = AZ::NonUniformScaleChangedEvent::Handler( @@ -394,7 +393,6 @@ namespace PhysX m_nonUniformScaleChangedHandler.Disconnect(); EditorColliderComponentRequestBus::Handler::BusDisconnect(); AZ::Render::MeshComponentNotificationBus::Handler::BusDisconnect(); - LmbrCentral::MeshComponentNotificationBus::Handler::BusDisconnect(); ColliderShapeRequestBus::Handler::BusDisconnect(); AzToolsFramework::BoxManipulatorRequestBus::Handler::BusDisconnect(); AZ::TransformNotificationBus::Handler::BusDisconnect(); @@ -1179,17 +1177,7 @@ namespace PhysX AZ::Render::MeshComponentRequestBus::EventResult(atomMeshAsset, GetEntityId(), &AZ::Render::MeshComponentRequestBus::Events::GetModelAsset); - if (atomMeshAsset.GetId().IsValid()) - { - return atomMeshAsset; - } - - // Try legacy render MeshComponent - AZ::Data::Asset legacyMeshAsset; - LmbrCentral::MeshComponentRequestBus::EventResult(legacyMeshAsset, - GetEntityId(), &LmbrCentral::MeshComponentRequests::GetMeshAsset); - - return legacyMeshAsset; + return atomMeshAsset; } void EditorColliderComponent::SetCollisionMeshFromRender() @@ -1264,14 +1252,6 @@ namespace PhysX renderMeshAsset.GetHint().c_str()); } } - - void EditorColliderComponent::OnMeshCreated([[maybe_unused]] const AZ::Data::Asset& asset) - { - if (ShouldUpdateCollisionMeshFromRender()) - { - SetCollisionMeshFromRender(); - } - } void EditorColliderComponent::OnModelReady([[maybe_unused]] const AZ::Data::Asset& modelAsset, [[maybe_unused]] const AZ::Data::Instance& model) diff --git a/Gems/PhysX/Code/Source/EditorColliderComponent.h b/Gems/PhysX/Code/Source/EditorColliderComponent.h index f179525802..e78be1b959 100644 --- a/Gems/PhysX/Code/Source/EditorColliderComponent.h +++ b/Gems/PhysX/Code/Source/EditorColliderComponent.h @@ -32,8 +32,6 @@ #include #include -#include - #include #include #include @@ -105,7 +103,6 @@ namespace PhysX , private PhysX::MeshColliderComponentRequestsBus::Handler , private AZ::TransformNotificationBus::Handler , private PhysX::ColliderShapeRequestBus::Handler - , private LmbrCentral::MeshComponentNotificationBus::Handler , private AZ::Render::MeshComponentNotificationBus::Handler , private PhysX::EditorColliderComponentRequestBus::Handler , private Physics::WorldBodyRequestBus::Handler @@ -175,9 +172,6 @@ namespace PhysX AZ::Transform GetCurrentTransform() override; AZ::Vector3 GetBoxScale() override; - // LmbrCentral::MeshComponentNotificationBus - void OnMeshCreated(const AZ::Data::Asset& asset) override; - // AZ::Render::MeshComponentNotificationBus void OnModelReady(const AZ::Data::Asset& modelAsset, const AZ::Data::Instance& model) override; diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp index 8be67fe89b..592a8e2a75 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.cpp @@ -290,7 +290,7 @@ namespace AZ::SceneGenerationComponents const bool hasBlendShapes = HasAnyBlendShapeChild(graph, nodeIndex); - auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); + auto [optimizedMesh, optimizedUVs, optimizedTangents, optimizedBitangents, optimizedVertexColors, optimizedSkinWeights] = OptimizeMesh(mesh, mesh, uvDatas, tangentDatas, bitangentDatas, colorDatas, skinWeightDatas, meshGroup, hasBlendShapes); const NodeIndex optimizedMeshNodeIndex = graph.AddChild(graph.GetNodeParent(nodeIndex), name.c_str(), AZStd::move(optimizedMesh)); @@ -322,7 +322,7 @@ namespace AZ::SceneGenerationComponents for (const NodeIndex& blendShapeNodeIndex : nodeIndexes(Containers::MakeDerivedFilterView(childNodes(nodeIndex)))) { const IBlendShapeData* blendShapeNode = static_cast(graph.GetNodeContent(blendShapeNodeIndex).get()); - auto [optimizedBlendShape, _1, _2, _3 , _4, _5] = OptimizeMesh(blendShapeNode, {}, {}, {}, {}, {}, meshGroup, hasBlendShapes); + auto [optimizedBlendShape, _1, _2, _3 , _4, _5] = OptimizeMesh(blendShapeNode, mesh, {}, {}, {}, {}, {}, meshGroup, hasBlendShapes); const AZStd::string optimizedName {graph.GetNodeName(blendShapeNodeIndex).GetName(), graph.GetNodeName(blendShapeNodeIndex).GetNameLength()}; const NodeIndex optimizedNodeIndex = graph.AddChild(optimizedMeshNodeIndex, optimizedName.c_str(), AZStd::move(optimizedBlendShape)); @@ -383,6 +383,7 @@ namespace AZ::SceneGenerationComponents AZStd::unique_ptr > MeshOptimizerComponent::OptimizeMesh( const MeshDataType* meshData, + const IMeshData* baseMesh, const AZStd::vector>& uvs, const AZStd::vector>& tangents, const AZStd::vector>& bitangents, @@ -441,7 +442,7 @@ namespace AZ::SceneGenerationComponents const AZ::u32 faceCount = meshData->GetFaceCount(); for (AZ::u32 faceIndex = 0; faceIndex < faceCount; ++faceIndex) { - meshBuilder.BeginPolygon(GetFaceMaterialId(meshData, faceIndex)); + meshBuilder.BeginPolygon(baseMesh->GetFaceMaterialId(faceIndex)); for (const AZ::u32 vertexIndex : meshData->GetFaceInfo(faceIndex).vertexIndex) { const int orgVertexNumber = meshData->GetUsedPointIndexForControlPoint(meshData->GetControlPointIndex(vertexIndex)); @@ -584,15 +585,6 @@ namespace AZ::SceneGenerationComponents ); } - unsigned int MeshOptimizerComponent::GetFaceMaterialId([[maybe_unused]] const AZ::SceneAPI::DataTypes::IBlendShapeData* meshData, [[maybe_unused]] unsigned int index) - { - return 0; - } - unsigned int MeshOptimizerComponent::GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IMeshData* meshData, unsigned int index) - { - return meshData->GetFaceMaterialId(index); - } - void MeshOptimizerComponent::AddFace(AZ::SceneData::GraphData::BlendShapeData* blendShape, unsigned int index1, unsigned int index2, unsigned int index3, [[maybe_unused]] unsigned int faceMaterialId) { blendShape->AddFace({index1, index2, index3}); diff --git a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h index ee8fa5afe5..e499f30e2e 100644 --- a/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h +++ b/Gems/SceneProcessing/Code/Source/Generation/Components/MeshOptimizer/MeshOptimizerComponent.h @@ -66,6 +66,7 @@ namespace AZ::SceneGenerationComponents AZStd::unique_ptr > OptimizeMesh( const MeshDataType* meshData, + const SceneAPI::DataTypes::IMeshData* baseMesh, const AZStd::vector>& uvs, const AZStd::vector>& tangents, const AZStd::vector>& bitangents, @@ -74,9 +75,6 @@ namespace AZ::SceneGenerationComponents const AZ::SceneAPI::DataTypes::IMeshGroup& meshGroup, bool hasBlendShapes); - static unsigned int GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IBlendShapeData* meshData, unsigned int index); - static unsigned int GetFaceMaterialId(const AZ::SceneAPI::DataTypes::IMeshData* meshData, unsigned int index); - static void AddFace(AZ::SceneData::GraphData::BlendShapeData* blendShape, unsigned int index1, unsigned int index2, unsigned int index3, unsigned int faceMaterialId); static void AddFace(AZ::SceneData::GraphData::MeshData* mesh, unsigned int index1, unsigned int index2, unsigned int index3, unsigned int faceMaterialId); }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja index 27498a2aec..71681ed73b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja @@ -186,21 +186,16 @@ void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) {% if attribute_Category is defined %} - ->Attribute(AZ::Edit::Attributes::Category, "{{ attribute_Category }}") + ->Attribute(AZ::Edit::Attributes::Category, "{{ attribute_Category }}") {%- endif %} - {% if attribute_Icon is defined %} - ->Attribute(AZ::Edit::Attributes::Icon, "{{ attribute_Icon }}") + ->Attribute(AZ::Edit::Attributes::Icon, "{{ attribute_Icon }}") {%- endif %} - {% if attribute_Deprecated is defined %} - ->Attribute(AZ::Edit::Attributes::Deprecated, "{{ attribute_Deprecated }}") + ->Attribute(AZ::Edit::Attributes::Deprecated, "{{ attribute_Deprecated }}") {%- endif %} - {% set uihandler = 'AZ::Edit::UIHandlers::Default' %} - -{% for Property in Class.iter('Property') %} -{% for item in Property.iter('PropertyData') %} +{% for item in Class.iter('Property') %} {% if item.attrib['UIHandler'] is defined %} {% set uihandler = item.attrib['UIHandler'] %} {% endif %} @@ -208,12 +203,11 @@ void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) {% if item.attrib['Description'] is defined %} {% set description = item.attrib['Description'] %} {% endif %} - // {{ item.attrib['Name'] }} - ->DataElement({{ uihandler }}, &{{ attribute_Name }}::{{ Property.attrib['Name'] }}, "{{ item.attrib['Name'] }}", "{{ description }}") -{% for EditAttribute in Property.iter('EditAttribute') %} - ->Attribute({{ EditAttribute.attrib['Key'] }}, {{ EditAttribute.attrib['Value'] }}) -{% endfor %} -{% endfor %} + // {{ item.attrib['Name'] }} + ->DataElement({{ uihandler }}, &{{ attribute_Name }}::{{ item.attrib['Name'] }}, "{{ item.attrib['Name'] }}", "{{ description }}") +{% for EditAttribute in item.iter('EditAttribute') %} + ->Attribute({{ EditAttribute.attrib['Key'] }}, {{ EditAttribute.attrib['Value'] }}) +{% endfor %} {% endfor %} ; } diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h index cb3c9cdccb..7f026edf58 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h @@ -122,6 +122,8 @@ namespace ScriptCanvasTests ::Nodes::InputTypeExampleNode::Reflect(m_behaviorContext); ::Nodes::BranchInputTypeExampleNode::Reflect(m_serializeContext); ::Nodes::BranchInputTypeExampleNode::Reflect(m_behaviorContext); + ::Nodes::PropertyExampleNode::Reflect(m_serializeContext); + ::Nodes::PropertyExampleNode::Reflect(m_behaviorContext); TestNodeableObject::Reflect(m_serializeContext); TestNodeableObject::Reflect(m_behaviorContext); diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/NodeableTestingLibrary.cpp b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/NodeableTestingLibrary.cpp index 6a9f7fd6c3..5d8574fb10 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/NodeableTestingLibrary.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/NodeableTestingLibrary.cpp @@ -44,6 +44,7 @@ namespace ScriptCanvasTesting ScriptCanvas::Library::AddNodeToRegistry(nodeRegistry); ScriptCanvas::Library::AddNodeToRegistry(nodeRegistry); ScriptCanvas::Library::AddNodeToRegistry(nodeRegistry); + ScriptCanvas::Library::AddNodeToRegistry(nodeRegistry); } AZStd::vector NodeableTestingLibrary::GetComponentDescriptors() @@ -53,7 +54,8 @@ namespace ScriptCanvasTesting ::Nodes::BranchMethodSharedDataSlotExampleNode::CreateDescriptor(), ::Nodes::ReturnTypeExampleNode::CreateDescriptor(), ::Nodes::InputTypeExampleNode::CreateDescriptor(), - ::Nodes::BranchInputTypeExampleNode::CreateDescriptor() + ::Nodes::BranchInputTypeExampleNode::CreateDescriptor(), + ::Nodes::PropertyExampleNode::CreateDescriptor() }); } } diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.ScriptCanvasNodeable.xml b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.ScriptCanvasNodeable.xml index efebbefce7..0be3c8c81a 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.ScriptCanvasNodeable.xml +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.ScriptCanvasNodeable.xml @@ -32,7 +32,7 @@ - + @@ -51,13 +51,27 @@ Namespace="None" Description="Example of passing as input by value, pointer and reference."> - + - + - + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp index 154508d5f1..35fa1136f9 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.cpp @@ -66,5 +66,15 @@ namespace ScriptCanvasTesting { input.clear(); } + + void PropertyExample::In() + { + for (auto& num : Numbers) + { + AZ_TracePrintf("ScriptCanvas", "%f", num); + } + + AZ_TracePrintf("ScriptCanvas", "Slang: %s", Slang.c_str()); + } } } diff --git a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.h b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.h index 7bcfed8bb4..8c19e1916c 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Nodes/Nodeables/ValuePointerReferenceExample.h @@ -48,5 +48,11 @@ namespace ScriptCanvasTesting { SCRIPTCANVAS_NODE(InputTypeExample); }; + + class PropertyExample + : public ScriptCanvas::Nodeable + { + SCRIPTCANVAS_NODE(PropertyExample); + }; } } diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Normal.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Pressed.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Sliced_Selected.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Normal.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Pressed.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Button_Stretched_Selected.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check_Background.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check_Background.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Check_Background.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Cross.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Cross.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Cross.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Off.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Off.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_Off.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/CheckBox_On.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_On.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/CheckBox_On.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Disabled.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Hover.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Hover.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Hover.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Normal.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Checkbox_Background_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Checkered.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Disabled.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Hover.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Hover.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Hover.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Normal.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Background_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Sliced.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Sliced.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Sliced.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Stretch.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Stretch.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Fill_Stretch.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Manipulator.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Manipulator.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Manipulator.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Sliced.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Sliced.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Sliced.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Stretch.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Stretch.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Slider_Track_Stretch.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Normal.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Pressed.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.assetinfo b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.exportsettings b/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.exportsettings deleted file mode 100644 index 1415bea891..0000000000 --- a/Gems/UiBasics/Assets/Textures/Basic/Text_Input_Sliced_Selected.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /dns=1 /preset=ReferenceImage_Linear /reduce=0 /ser=0 diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Arrow.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Arrow.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Arrow.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowL.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowL.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowL.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowR.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowR.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowR.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowU.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowU.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_ArrowU.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Button.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Button.tif.assetinfo new file mode 100644 index 0000000000..95b548a2eb --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Button.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Menu.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Menu.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/Dropdown_Menu.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Hover.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Hover.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Hover.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Background_Normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Dot.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Dot.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/RadioButton_Dot.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/button_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/button_disabled.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/button_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/button_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/button_normal.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/button_normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_hover.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_hover.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_hover.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_normal.tif.assetinfo new file mode 100644 index 0000000000..2eb5be8e93 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_box_normal.tif.assetinfo @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_check.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_check.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/checkbox_check.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_handle.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_handle.tif.assetinfo new file mode 100644 index 0000000000..95b548a2eb --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_handle.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_horiz_track.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_horiz_track.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_horiz_track.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_vert_track.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_vert_track.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/scrollbar_vert_track.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_fill_normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_disabled.tif.assetinfo new file mode 100644 index 0000000000..95b548a2eb --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_handle_normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_disabled.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_normal.tif.assetinfo new file mode 100644 index 0000000000..61b2832ff3 --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/slider_track_normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_disabled.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_disabled.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_disabled.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_hover.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_hover.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_hover.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_normal.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_normal.tif.assetinfo new file mode 100644 index 0000000000..c6f6ca1e9c --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/textinput_normal.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/UiBasics/Assets/UI/Textures/Prefab/tooltip_sliced.tif.assetinfo b/Gems/UiBasics/Assets/UI/Textures/Prefab/tooltip_sliced.tif.assetinfo new file mode 100644 index 0000000000..dd1d22706e --- /dev/null +++ b/Gems/UiBasics/Assets/UI/Textures/Prefab/tooltip_sliced.tif.assetinfo @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/OccluderArea_white.png b/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/OccluderArea_white.png deleted file mode 100644 index 5554bfc38e..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/OccluderArea_white.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46757cf327aa9ed60ded1f3025140bc065569634f69e5aaba0b83086fa7642e0 -size 786 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/Portal_white.png b/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/Portal_white.png deleted file mode 100644 index fc72adc85e..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/Portal_white.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44150d202f318598e939bf29a543b6edaa0d2cf7455989a2d0da916ba7c83384 -size 833 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/VisArea_white.png b/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/VisArea_white.png deleted file mode 100644 index 48a7af896a..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Disabled/VisArea_white.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44570118c315725d13affcc87b0eb4fb01f01cf67f9da0a4e066a347e096a36f -size 757 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/OccluderArea.svg b/Gems/Visibility/Assets/Editor/Icons/Components/OccluderArea.svg deleted file mode 100644 index aa8840a798..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/OccluderArea.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - icon / Rendering / OccluderArea - Created with Sketch. - - - - - - - - - - diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Portal.svg b/Gems/Visibility/Assets/Editor/Icons/Components/Portal.svg deleted file mode 100644 index 967a891222..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Portal.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - icon / Rendering / Portal - Created with Sketch. - - - - - - - - - - diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/OccluderArea.png b/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/OccluderArea.png deleted file mode 100644 index 3e98e852dd..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/OccluderArea.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7288c80d906ec59271ccd4db168d318f4c5b4fd65fca6077acbf4aaeb76b9e24 -size 4081 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/Portal.png b/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/Portal.png deleted file mode 100644 index b7198e5803..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/Portal.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:486816ea8e6cb090f8d78e26d9ed6a73aca8e5d6c5fb6bcb3cb2fff8277053db -size 4687 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/VisArea.png b/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/VisArea.png deleted file mode 100644 index e2d0c7f803..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/Viewport/VisArea.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aca391fc79c7b5400465bcdaa3a1c21a0fbb3dd042420b6511ecf568048ee6ec -size 4558 diff --git a/Gems/Visibility/Assets/Editor/Icons/Components/VisArea.svg b/Gems/Visibility/Assets/Editor/Icons/Components/VisArea.svg deleted file mode 100644 index 389f4cf35d..0000000000 --- a/Gems/Visibility/Assets/Editor/Icons/Components/VisArea.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - icon / Rendering / VisArea - Created with Sketch. - - - - - - - - - - diff --git a/Gems/Visibility/CMakeLists.txt b/Gems/Visibility/CMakeLists.txt deleted file mode 100644 index 20a680bce9..0000000000 --- a/Gems/Visibility/CMakeLists.txt +++ /dev/null @@ -1,12 +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. -# - -add_subdirectory(Code) diff --git a/Gems/Visibility/Code/CMakeLists.txt b/Gems/Visibility/Code/CMakeLists.txt deleted file mode 100644 index c8650eea79..0000000000 --- a/Gems/Visibility/Code/CMakeLists.txt +++ /dev/null @@ -1,105 +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. -# - -ly_add_target( - NAME Visibility.Static STATIC - NAMESPACE Gem - FILES_CMAKE - visibility_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PUBLIC - Legacy::CryCommon -) - -ly_add_target( - NAME Visibility ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE} - NAMESPACE Gem - FILES_CMAKE - visibility_shared_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - Gem::Visibility.Static -) - -if(PAL_TRAIT_BUILD_HOST_TOOLS) - - ly_add_target( - NAME Visibility.Editor.Static STATIC - NAMESPACE Gem - FILES_CMAKE - visibility_editor_files.cmake - COMPILE_DEFINITIONS - PUBLIC - VISIBILITY_EDITOR - INCLUDE_DIRECTORIES - PRIVATE - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PUBLIC - Legacy::Editor.Headers - Legacy::EditorCore - AZ::AzToolsFramework - Gem::Visibility.Static - ) - - ly_add_target( - NAME Visibility.Editor GEM_MODULE - - NAMESPACE Gem - FILES_CMAKE - visibility_editor_shared_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Source - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - Gem::Visibility.Editor.Static - ) -endif() - -################################################################################ -# Tests -################################################################################ -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_target( - NAME Visibility.Editor.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - visibility_editor_tests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Tests - Source - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Gem::Visibility.Editor.Static - ) - ly_add_googletest( - NAME Gem::Visibility.Editor.Tests - ) - endif() -endif() diff --git a/Gems/Visibility/Code/Include/EditorOccluderAreaComponentBus.h b/Gems/Visibility/Code/Include/EditorOccluderAreaComponentBus.h deleted file mode 100644 index f2714691cb..0000000000 --- a/Gems/Visibility/Code/Include/EditorOccluderAreaComponentBus.h +++ /dev/null @@ -1,54 +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 "OccluderAreaComponentBus.h" - -namespace Visibility -{ - /// Request bus for the EditorOccluderComponent. - class EditorOccluderAreaRequests - : public OccluderAreaRequests - , public AZ::FixedVertices - { - public: - virtual void SetDisplayFilled(bool displayFilled) = 0; - virtual void SetCullDistRatio(float cullDistRatio) = 0; - virtual void SetUseInIndoors(bool inDoors) = 0; - virtual void SetDoubleSide(bool doubleSided) = 0; - virtual void UpdateOccluderAreaObject() = 0; - - protected: - ~EditorOccluderAreaRequests() = default; - }; - - /// Type to inherit to implement EditorOccluderAreaComponentRequests - using EditorOccluderAreaRequestBus = AZ::EBus; - - /// Editor notification bus for EditorOccluderAreaComponent. - class EditorOccluderAreaNotifications - : public AZ::ComponentBus - { - public: - virtual void OnVerticesChangedInspector() {} - - protected: - ~EditorOccluderAreaNotifications() = default; - }; - - /// Type to inherit to implement EditorOccluderAreaNotifications. - using EditorOccluderAreaNotificationBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Include/EditorPortalComponentBus.h b/Gems/Visibility/Code/Include/EditorPortalComponentBus.h deleted file mode 100644 index c4ab43d8a0..0000000000 --- a/Gems/Visibility/Code/Include/EditorPortalComponentBus.h +++ /dev/null @@ -1,60 +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 "PortalComponentBus.h" - -namespace Visibility -{ - /// Request bus for the EditorPortalComponent. - class EditorPortalRequests - : public PortalRequests - , public AZ::FixedVertices - { - public: - virtual void SetHeight(float height) = 0; - virtual void SetDisplayFilled(bool filled) = 0; - virtual void SetAffectedBySun(bool affectedBySun) = 0; - virtual void SetViewDistRatio(float viewDistRatio) = 0; - virtual void SetSkyOnly(bool skyOnly) = 0; - virtual void SetOceanIsVisible(bool oceanVisible) = 0; - virtual void SetUseDeepness(bool useDeepness) = 0; - virtual void SetDoubleSide(bool doubleSided) = 0; - virtual void SetLightBlending(bool lightBending) = 0; - virtual void SetLightBlendValue(float lightBendAmount) = 0; - virtual void UpdatePortalObject() = 0; - - protected: - ~EditorPortalRequests() = default; - }; - - /// Type to inherit to implement EditorPortalComponentRequests - using EditorPortalRequestBus = AZ::EBus; - - /// Editor notification bus for EditorPortalComponent. - class EditorPortalNotifications - : public AZ::ComponentBus - { - public: - virtual void OnVerticesChangedInspector() {} - - protected: - ~EditorPortalNotifications() = default; - }; - - /// Type to inherit to implement EditorPortalNotifications. - using EditorPortalNotificationBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Include/EditorVisAreaComponentBus.h b/Gems/Visibility/Code/Include/EditorVisAreaComponentBus.h deleted file mode 100644 index 6803ea77a6..0000000000 --- a/Gems/Visibility/Code/Include/EditorVisAreaComponentBus.h +++ /dev/null @@ -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. -* -*/ - -#pragma once - -#include - -#include "VisAreaComponentBus.h" - -namespace Visibility -{ - /// Request bus for the EditorVisAreaComponent. - class EditorVisAreaComponentRequests - : public VisAreaComponentRequests - , public AZ::VariableVertices - { - public: - virtual void SetHeight(float height) = 0; - virtual void SetDisplayFilled(bool filled) = 0; - virtual void SetAffectedBySun(bool affectedBySun) = 0; - virtual void SetViewDistRatio(float viewDistRatio) = 0; - virtual void SetOceanIsVisible(bool oceanVisible) = 0; - virtual void UpdateVisAreaObject() = 0; - }; - - /// Type to inherit to implement EditorVisAreaComponentRequests. - using EditorVisAreaComponentRequestBus = AZ::EBus; - - /// Notification bus for the EditorVisAreaComponent. - class EditorVisAreaComponentNotifications - : public AZ::ComponentBus - , public AZ::VertexContainerNotificationInterface - { - public: - /// Called when a new vertex is added to the vis area. - void OnVertexAdded(size_t /*index*/) override {} - - /// Called when a vertex is removed from the vis area. - void OnVertexRemoved(size_t /*index*/) override {} - - /// Called when a vertex is updated. - void OnVertexUpdated(size_t /*index*/) override {} - - /// Called when all vertices on the vis area are set. - void OnVerticesSet(const AZStd::vector& /*vertices*/) override {} - - /// Called when all vertices are removed from the vis area. - void OnVerticesCleared() override {} - - protected: - ~EditorVisAreaComponentNotifications() = default; - }; - - /// Type to inherit to implement EditorVisAreaComponentNotifications. - using EditorVisAreaComponentNotificationBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Include/OccluderAreaComponentBus.h b/Gems/Visibility/Code/Include/OccluderAreaComponentBus.h deleted file mode 100644 index 21b66c14c1..0000000000 --- a/Gems/Visibility/Code/Include/OccluderAreaComponentBus.h +++ /dev/null @@ -1,37 +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 -#include - -namespace Visibility -{ - /// Request bus for the OccluderAreaComponent. - class OccluderAreaRequests - { - public: - virtual bool GetDisplayFilled() = 0; - virtual float GetCullDistRatio() = 0; - virtual bool GetUseInIndoors() = 0; - virtual bool GetDoubleSide() = 0; - - protected: - ~OccluderAreaRequests() = default; - }; - - /// Type to inherit to implement OccluderAreaRequests. - using OccluderAreaRequestBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Include/PortalComponentBus.h b/Gems/Visibility/Code/Include/PortalComponentBus.h deleted file mode 100644 index 7de4cb4e80..0000000000 --- a/Gems/Visibility/Code/Include/PortalComponentBus.h +++ /dev/null @@ -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 -#include -#include - -namespace Visibility -{ - // Request bus for the PortalComponent. - class PortalRequests - { - public: - virtual float GetHeight() = 0; - virtual bool GetDisplayFilled() = 0; - virtual bool GetAffectedBySun() = 0; - virtual float GetViewDistRatio() = 0; - virtual bool GetSkyOnly() = 0; - virtual bool GetOceanIsVisible() = 0; - virtual bool GetUseDeepness() = 0; - virtual bool GetDoubleSide() = 0; - virtual bool GetLightBlending() = 0; - virtual float GetLightBlendValue() = 0; - - protected: - ~PortalRequests() = default; - }; - - /// Type to inherit to implement PortalRequests. - using PortalRequestBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Include/VisAreaComponentBus.h b/Gems/Visibility/Code/Include/VisAreaComponentBus.h deleted file mode 100644 index 632e68ffc5..0000000000 --- a/Gems/Visibility/Code/Include/VisAreaComponentBus.h +++ /dev/null @@ -1,38 +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 -#include - -namespace Visibility -{ - /// Request bus for the VisAreaComponent. - class VisAreaComponentRequests - { - public: - virtual float GetHeight() = 0; - virtual bool GetDisplayFilled() = 0; - virtual bool GetAffectedBySun() = 0; - virtual float GetViewDistRatio() = 0; - virtual bool GetOceanIsVisible() = 0; - - protected: - ~VisAreaComponentRequests() = default; - }; - - /// Type to inherit to implement VisAreaComponentRequests. - using VisAreaComponentRequestBus = AZ::EBus; - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.cpp b/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.cpp deleted file mode 100644 index 9a88799a31..0000000000 --- a/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.cpp +++ /dev/null @@ -1,437 +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 "Visibility_precompiled.h" -#include "EditorOccluderAreaComponent.h" -#include "EditorOccluderAreaComponentMode.h" - -#include -#include -#include -#include -#include -#include - -// Include files needed for writing DisplayEntity functions that access the DisplayContext directly. -#include - -#include "MathConversion.h" - -namespace Visibility -{ - void EditorOccluderAreaComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides) - { - provides.push_back(AZ_CRC("EditorOccluderAreaService", 0xf943e16a)); - provides.push_back(AZ_CRC("OccluderAreaService", 0x2fefad66)); - provides.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorOccluderAreaComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires) - { - requires.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - void EditorOccluderAreaComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - dependent.push_back(AZ_CRC("QuadShapeService", 0xe449b0fc)); - } - - void EditorOccluderAreaComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("EditorOccluderAreaService", 0xf943e16a)); - incompatible.push_back(AZ_CRC("OccluderAreaService", 0x2fefad66)); - incompatible.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorOccluderAreaConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1); - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("OccluderArea Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true); - - editContext->Class("OccluderArea Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &OccluderAreaConfiguration::m_displayFilled, "DisplayFilled", "Display the Occlude Area as a filled quad.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OccluderAreaConfiguration::OnChange) - ->DataElement(AZ::Edit::UIHandlers::Default, &OccluderAreaConfiguration::m_cullDistRatio, "CullDistRatio", "The range of the culling effect.") - ->Attribute(AZ::Edit::Attributes::Max, 100.0f) - ->Attribute(AZ::Edit::Attributes::Min, 0.0f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OccluderAreaConfiguration::OnChange) - ->DataElement(AZ::Edit::UIHandlers::Default, &OccluderAreaConfiguration::m_useInIndoors, "UseInIndoors", "Should this occluder work inside VisAreas.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OccluderAreaConfiguration::OnChange) - ->DataElement(AZ::Edit::UIHandlers::Default, &OccluderAreaConfiguration::m_doubleSide, "DoubleSide", "Should this occlude from both sides.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OccluderAreaConfiguration::OnChange) - ->DataElement(AZ::Edit::UIHandlers::Default, &OccluderAreaConfiguration::m_vertices, "Vertices", "Points that make up the OccluderArea.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &OccluderAreaConfiguration::OnVerticesChange) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; - } - } - } - - void EditorOccluderAreaComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(2) - ->Field("m_config", &EditorOccluderAreaComponent::m_config) - ->Field("ComponentMode", &EditorOccluderAreaComponent::m_componentModeDelegate) - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("OccluderArea", "An area that blocks objects behind it from rendering.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Rendering") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/OccluderArea.png") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/OccluderArea.svg") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "http://docs.aws.amazon.com/console/lumberyard/userguide/occluder-area-component") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorOccluderAreaComponent::m_config, "m_config", "No Description") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorOccluderAreaComponent::m_componentModeDelegate, "Component Mode", "OccluderArea Component Mode") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("EditorOccluderAreaRequestBus") - ->Event("SetDisplayFilled", &EditorOccluderAreaRequestBus::Events::SetDisplayFilled) - ->Event("GetDisplayFilled", &EditorOccluderAreaRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", "SetDisplayFilled") - - ->Event("SetCullDistRatio", &EditorOccluderAreaRequestBus::Events::SetCullDistRatio) - ->Event("GetCullDistRatio", &EditorOccluderAreaRequestBus::Events::GetCullDistRatio) - ->VirtualProperty("CullDistRatio", "GetCullDistRatio", "SetCullDistRatio") - - ->Event("SetUseInIndoors", &EditorOccluderAreaRequestBus::Events::SetUseInIndoors) - ->Event("GetUseInIndoors", &EditorOccluderAreaRequestBus::Events::GetUseInIndoors) - ->VirtualProperty("UseInIndoors", "GetUseInIndoors", "SetUseInIndoors") - - ->Event("SetDoubleSide", &EditorOccluderAreaRequestBus::Events::SetDoubleSide) - ->Event("GetDoubleSide", &EditorOccluderAreaRequestBus::Events::GetDoubleSide) - ->VirtualProperty("DoubleSide", "GetDoubleSide", "SetDoubleSide") - ; - - behaviorContext->Class()->RequestBus("EditorOccluderAreaRequestBus"); - } - - EditorOccluderAreaConfiguration::Reflect(context); - } - - void EditorOccluderAreaConfiguration::OnChange() - { - EditorOccluderAreaRequestBus::Event(m_entityId, &EditorOccluderAreaRequests::UpdateOccluderAreaObject); - } - - void EditorOccluderAreaConfiguration::OnVerticesChange() - { - EditorOccluderAreaRequestBus::Event( - m_entityId, &EditorOccluderAreaRequests::UpdateOccluderAreaObject); - EditorOccluderAreaNotificationBus::Event( - m_entityId, &EditorOccluderAreaNotifications::OnVerticesChangedInspector); - } - - void EditorOccluderAreaConfiguration::SetEntityId(const AZ::EntityId entityId) - { - m_entityId = entityId; - } - - EditorOccluderAreaComponent::~EditorOccluderAreaComponent() - { - if (m_area) - { - GetIEditor()->Get3DEngine()->DeleteVisArea(m_area); - m_area = nullptr; - } - } - - void EditorOccluderAreaComponent::Activate() - { - Base::Activate(); - - const AZ::EntityId entityId = GetEntityId(); - m_config.SetEntityId(entityId); - - // NOTE: We create the vis-area here at activate, but destroy it in the destructor. - // We have to do this, otherwise the vis-area is not saved into the level. - // Unfortunately, at this time we cannot create the vis-areas at game runtime. - // This means that dynamic slices cannot effectively contain vis areas until we fix - // the core rendering system to allow that. - const auto visGUID = static_cast(entityId); - if(!m_area && GetIEditor()) - { - m_area = GetIEditor()->Get3DEngine()->CreateVisArea(visGUID); - } - - m_componentModeDelegate.ConnectWithSingleComponentMode< - EditorOccluderAreaComponent, EditorOccluderAreaComponentMode>( - AZ::EntityComponentIdPair(entityId, GetId()), this); - - EditorOccluderAreaRequestBus::Handler::BusConnect(entityId); - AZ::FixedVerticesRequestBus::Handler::BusConnect(entityId); - AZ::TransformNotificationBus::Handler::BusConnect(entityId); - AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(entityId); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(entityId); - AzFramework::BoundsRequestBus::Handler::BusConnect(entityId); - - UpdateOccluderAreaObject(); - } - - void EditorOccluderAreaComponent::Deactivate() - { - m_componentModeDelegate.Disconnect(); - - AzFramework::BoundsRequestBus::Handler::BusDisconnect(); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusDisconnect(); - AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - AZ::FixedVerticesRequestBus::Handler::BusDisconnect(); - EditorOccluderAreaRequestBus::Handler::BusDisconnect(); - - Base::Deactivate(); - } - - /// Update the object runtime after changes to the Configuration. - /// Called by the default RequestBus SetXXX implementations, - /// and used to initially set up the object the first time the - /// Configuration are set. - void EditorOccluderAreaComponent::UpdateOccluderAreaObject() - { - if (m_area) - { - AZStd::array verts; - - const Matrix34& wtm = AZTransformToLYTransform(GetWorldTM()); - for (size_t i = 0; i < m_config.m_vertices.size(); ++i) - { - verts[i] = wtm.TransformPoint(AZVec3ToLYVec3(m_config.m_vertices[i])); - } - - SVisAreaInfo info; - info.fHeight = 0; - info.vAmbientColor = Vec3(0, 0, 0); - info.bAffectedByOutLights = false; - info.bSkyOnly = false; - info.fViewDistRatio = m_config.m_cullDistRatio; - info.bDoubleSide = m_config.m_doubleSide; - info.bUseDeepness = false; - info.bUseInIndoors = m_config.m_useInIndoors; - info.bOceanIsVisible = false; - info.fPortalBlending = -1.0f; - - const AZStd::string name = AZStd::string("OcclArea_") + GetEntity()->GetName(); - GetIEditor()->Get3DEngine()->UpdateVisArea(m_area, &verts[0], verts.size(), name.c_str(), info, false); - - AzFramework::EntityBoundsUnionRequestBus::Broadcast( - &AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); - } - } - - void EditorOccluderAreaComponent::SetDisplayFilled(const bool value) - { - m_config.m_displayFilled = value; - UpdateOccluderAreaObject(); - } - - bool EditorOccluderAreaComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - void EditorOccluderAreaComponent::SetCullDistRatio(const float value) - { - m_config.m_cullDistRatio = value; - UpdateOccluderAreaObject(); - } - - float EditorOccluderAreaComponent::GetCullDistRatio() - { - return m_config.m_cullDistRatio; - } - - void EditorOccluderAreaComponent::SetUseInIndoors(const bool value) - { - m_config.m_useInIndoors = value; - UpdateOccluderAreaObject(); - } - - bool EditorOccluderAreaComponent::GetUseInIndoors() - { - return m_config.m_useInIndoors; - } - - void EditorOccluderAreaComponent::SetDoubleSide(const bool value) - { - m_config.m_doubleSide = value; - UpdateOccluderAreaObject(); - } - - bool EditorOccluderAreaComponent::GetDoubleSide() - { - return m_config.m_doubleSide; - } - - bool EditorOccluderAreaComponent::GetVertex(const size_t index, AZ::Vector3& vertex) const - { - if (index < m_config.m_vertices.size()) - { - vertex = m_config.m_vertices[index]; - return true; - } - - return false; - } - - bool EditorOccluderAreaComponent::UpdateVertex(const size_t index, const AZ::Vector3& vertex) - { - if (index < m_config.m_vertices.size()) - { - m_config.m_vertices[index] = vertex; - return true; - } - - return false; - } - - void EditorOccluderAreaComponent::OnTransformChanged(const AZ::Transform& /*local*/, [[maybe_unused]] const AZ::Transform& world) - { - UpdateOccluderAreaObject(); - } - - void EditorOccluderAreaComponent::DisplayEntityViewport( - [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) - { - const AZ::Transform worldFromLocal = GetWorldTM(); - const AZ::Vector4 color(0.5f, 0.25f, 0.0f, 1.0f); - const AZ::Vector4 selectedColor(1.0f, 0.5f, 0.0f, 1.0f); - const float previousLineWidth = debugDisplay.GetLineWidth(); - - debugDisplay.DepthWriteOff(); - debugDisplay.PushMatrix(worldFromLocal); - debugDisplay.SetColor(IsSelected() ? selectedColor : color); - debugDisplay.SetLineWidth(5.0f); - debugDisplay.SetAlpha(0.8f); - - for (size_t i = 2; i < 4; i++) - { - // draw the plane - if (m_config.m_displayFilled) - { - debugDisplay.SetAlpha(0.3f); - debugDisplay.CullOff(); - debugDisplay.DrawTri(m_config.m_vertices[0], m_config.m_vertices[i - 1], m_config.m_vertices[i]); - debugDisplay.CullOn(); - debugDisplay.SetAlpha(0.8f); - } - - debugDisplay.DrawLine(m_config.m_vertices[i - 2], m_config.m_vertices[i - 1]); - debugDisplay.DrawLine(m_config.m_vertices[i - 1], m_config.m_vertices[i]); - } - - // draw the closing line - debugDisplay.DrawLine(m_config.m_vertices[3], m_config.m_vertices[0]); - - if (m_componentModeDelegate.AddedToComponentMode()) - { - AzToolsFramework::VertexContainerDisplay::DisplayVertexContainerIndices( - debugDisplay, AzToolsFramework::FixedVerticesArray(m_config.m_vertices), - GetWorldTM(), AZ::Vector3::CreateOne(), IsSelected()); - } - - debugDisplay.DepthWriteOn(); - debugDisplay.SetLineWidth(previousLineWidth); - debugDisplay.PopMatrix(); - } - - void EditorOccluderAreaComponent::BuildGameEntity(AZ::Entity* gameEntity) - { - gameEntity->CreateComponent(m_config); - } - - AZ::Aabb EditorOccluderAreaComponent::GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/) - { - return GetWorldBounds(); - } - - bool EditorOccluderAreaComponent::EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) - { - const float rayLength = 1000.0f; - AZ::Vector3 scaledDir = dir * rayLength; - AZ::Vector3 end = src + scaledDir; - float t; - float intermediateT = std::numeric_limits::max(); - bool didHit = false; - - // Transform verts to world space for tris test - AZStd::array verts; - const AZ::Transform& wtm = GetWorldTM(); - for (size_t i = 0; i < m_config.m_vertices.size(); ++i) - { - verts[i] = wtm.TransformPoint(m_config.m_vertices[i]); - } - - AZ::Vector3 normal; - for (AZ::u8 i = 2; i < 4; ++i) - { - if (AZ::Intersect::IntersectSegmentTriangleCCW(src, end, verts[0], verts[i - 1], verts[i], normal, t) > 0) - { - intermediateT = AZStd::GetMin(t, intermediateT); - didHit = true; - } - //Else if here as we shouldn't successfully ccw and cw intersect at the same time - else if (AZ::Intersect::IntersectSegmentTriangle(src, end, verts[0], verts[i - 1], verts[i], normal, t) > 0) - { - intermediateT = AZStd::GetMin(t, intermediateT); - didHit = true; - } - } - - if (didHit) - { - distance = intermediateT * rayLength; - } - return didHit; - } - - AZ::Aabb EditorOccluderAreaComponent::GetWorldBounds() - { - return GetLocalBounds().GetTransformedAabb(GetWorldTM()); - } - - AZ::Aabb EditorOccluderAreaComponent::GetLocalBounds() - { - AZ::Aabb bbox = AZ::Aabb::CreateNull(); - for (const auto& vertex : m_config.m_vertices) - { - bbox.AddPoint(vertex); - } - return bbox; - } -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.h b/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.h deleted file mode 100644 index 0ac6528bc7..0000000000 --- a/Gems/Visibility/Code/Source/EditorOccluderAreaComponent.h +++ /dev/null @@ -1,129 +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 "OccluderAreaComponent.h" -#include "EditorOccluderAreaComponentBus.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Visibility -{ - class EditorOccluderAreaComponent; - - class EditorOccluderAreaConfiguration - : public OccluderAreaConfiguration - { - public: - AZ_TYPE_INFO_LEGACY(EditorOccluderAreaConfiguration, "{032F466F-25CB-5460-AC2F-B04236C87878}", OccluderAreaConfiguration); - AZ_CLASS_ALLOCATOR(EditorOccluderAreaConfiguration, AZ::SystemAllocator, 0); - - static void Reflect(AZ::ReflectContext* context); - - void OnChange() override; - void OnVerticesChange() override; - - void SetEntityId(AZ::EntityId entityId); - - private: - AZ::EntityId m_entityId; - }; - - class EditorOccluderAreaComponent - : public AzToolsFramework::Components::EditorComponentBase - , private EditorOccluderAreaRequestBus::Handler - , private AZ::FixedVerticesRequestBus::Handler - , private AzFramework::EntityDebugDisplayEventBus::Handler - , private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler - , private AZ::TransformNotificationBus::Handler - , public AzFramework::BoundsRequestBus::Handler - { - friend class EditorOccluderAreaConfiguration; - - using Base = AzToolsFramework::Components::EditorComponentBase; - - public: - AZ_COMPONENT(EditorOccluderAreaComponent, "{1A209C7C-6C06-5AE6-AD60-22CD8D0DAEE3}", AzToolsFramework::Components::EditorComponentBase); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - static void Reflect(AZ::ReflectContext* context); - - EditorOccluderAreaComponent() = default; - EditorOccluderAreaComponent(const EditorOccluderAreaComponent&) = delete; - EditorOccluderAreaComponent& operator=(const EditorOccluderAreaComponent&) = delete; - ~EditorOccluderAreaComponent(); - - // AZ::Component overrides ... - void Activate() override; - void Deactivate() override; - void BuildGameEntity(AZ::Entity* gameEntity) override; - - // TransformNotificationBus overrides ... - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // EditorComponentSelectionRequestsBus overrides ... - AZ::Aabb GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& viewportInfo) override; - bool EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) override; - bool SupportsEditorRayIntersect() override { return true; } - - // BoundsRequestBus overrides ... - AZ::Aabb GetWorldBounds() override; - AZ::Aabb GetLocalBounds() override; - - /// EditorOccluderAreaRequestBus overrides ... - void SetDisplayFilled(bool value) override; - bool GetDisplayFilled() override; - void SetCullDistRatio(float value) override; - float GetCullDistRatio() override; - void SetUseInIndoors(bool value) override; - bool GetUseInIndoors() override; - void SetDoubleSide(bool value) override; - bool GetDoubleSide() override; - bool GetVertex(size_t index, AZ::Vector3& vertex) const override; - bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override; - size_t Size() const override { return m_config.m_vertices.size(); } - void UpdateOccluderAreaObject() override; - - private: - friend EditorOccluderAreaConfiguration; - - // AzFramework::EntityDebugDisplayEventBus overrides ... - void DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; - - // Reflected members - EditorOccluderAreaConfiguration m_config; - - using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate; - ComponentModeDelegate m_componentModeDelegate; ///< Responsible for detecting ComponentMode activation - ///< and creating a concrete ComponentMode. - - // Unreflected members - IVisArea* m_area = nullptr; - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.cpp b/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.cpp deleted file mode 100644 index 0ab51d362a..0000000000 --- a/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.cpp +++ /dev/null @@ -1,85 +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 "Visibility_precompiled.h" -#include "EditorOccluderAreaComponentMode.h" - -#include - -namespace Visibility -{ - AZ_CLASS_ALLOCATOR_IMPL(EditorOccluderAreaComponentMode, AZ::SystemAllocator, 0) - - EditorOccluderAreaComponentMode::EditorOccluderAreaComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType) - : EditorBaseComponentMode(entityComponentIdPair, componentType) - { - CreateManipulators(); - - AZ::TransformNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - EditorOccluderAreaNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - } - - EditorOccluderAreaComponentMode::~EditorOccluderAreaComponentMode() - { - EditorOccluderAreaNotificationBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - - m_vertexSelection.Destroy(); - } - - void EditorOccluderAreaComponentMode::CreateManipulators() - { - using namespace AzToolsFramework; - - m_vertexSelection.Create( - AZ::EntityComponentIdPair(GetEntityId(), GetComponentId()), g_mainManipulatorManagerId, - AZStd::make_unique(), - TranslationManipulators::Dimensions::Three, - ConfigureTranslationManipulatorAppearance3d); - - m_vertexSelection.SetVertexPositionsUpdatedCallback([this]() - { - EditorOccluderAreaRequestBus::Event( - GetEntityId(), &EditorOccluderAreaRequests::UpdateOccluderAreaObject); - }); - } - - void EditorOccluderAreaComponentMode::OnTransformChanged( - const AZ::Transform& /*local*/, const AZ::Transform& world) - { - m_vertexSelection.RefreshSpace(world); - } - - void EditorOccluderAreaComponentMode::OnVerticesChangedInspector() - { - m_vertexSelection.RefreshLocal(); - } - - void EditorOccluderAreaComponentMode::Refresh() - { - // destroy and recreate manipulators when container is modified (vertices are added or removed) - m_vertexSelection.Destroy(); - CreateManipulators(); - } - - AZStd::vector EditorOccluderAreaComponentMode::PopulateActionsImpl() - { - return m_vertexSelection.ActionOverrides(); - } - - bool EditorOccluderAreaComponentMode::HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) - { - return m_vertexSelection.HandleMouse(mouseInteraction); - } -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.h b/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.h deleted file mode 100644 index babef3bccc..0000000000 --- a/Gems/Visibility/Code/Source/EditorOccluderAreaComponentMode.h +++ /dev/null @@ -1,53 +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 -#include - -#include "EditorOccluderAreaComponentBus.h" - -namespace Visibility -{ - class EditorOccluderAreaComponentMode - : public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode - , private AZ::TransformNotificationBus::Handler - , private EditorOccluderAreaNotificationBus::Handler - { - public: - AZ_CLASS_ALLOCATOR_DECL - - EditorOccluderAreaComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType); - ~EditorOccluderAreaComponentMode(); - - private: - // EditorBaseComponentMode - void Refresh() override; - AZStd::vector PopulateActionsImpl() override; - bool HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; - - // Manipulator handling - void CreateManipulators(); - - // TransformNotificationBus - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // OccluderAreaNotificationBus - void OnVerticesChangedInspector() override; - - AzToolsFramework::EditorVertexSelectionFixed m_vertexSelection; ///< Handles all manipulator interactions with vertices. - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorPortalComponent.cpp b/Gems/Visibility/Code/Source/EditorPortalComponent.cpp deleted file mode 100644 index 4e1b07991a..0000000000 --- a/Gems/Visibility/Code/Source/EditorPortalComponent.cpp +++ /dev/null @@ -1,785 +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 "Visibility_precompiled.h" -#include "EditorPortalComponent.h" -#include "EditorPortalComponentMode.h" - -#include - -// Include files needed for writing DisplayEntity functions that access the DisplayContext directly. -#include - -#include -#include -#include -#include -#include - -namespace Visibility -{ - void EditorPortalComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("EditorPortalService", 0x6ead38f6)); - provided.push_back(AZ_CRC("PortalService", 0x06076210)); - provided.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorPortalComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - required.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - void EditorPortalComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - dependent.push_back(AZ_CRC("QuadShapeService", 0xe449b0fc)); - } - - void EditorPortalComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("SphereShapeService", 0x90c8dc80)); - incompatible.push_back(AZ_CRC("SplineShapeService", 0x4d4b94a2)); - incompatible.push_back(AZ_CRC("PolygonPrismShapeService", 0x1cbc4ed4)); - incompatible.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorPortalConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1); - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("Portal Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true); - - editContext->Class("Portal Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_height, "Height", "How tall the Portal is.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_displayFilled, "DisplayFilled", "Display the Portal as a filled volume.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_affectedBySun, "AffectedBySun", "Allows sunlight to affect objects inside the Portal.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_viewDistRatio, "ViewDistRatio", "Specifies how far the Portal is rendered.") - ->Attribute(AZ::Edit::Attributes::Max, 100.000000) - ->Attribute(AZ::Edit::Attributes::Min, 0.000000) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_skyOnly, "SkyOnly", "Only the Sky Box will render when looking outside the Portal.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_oceanIsVisible, "OceanIsVisible", "Ocean will be visible when looking outside the Portal.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_useDeepness, "UseDeepness", "Portal will be treated as an object with volume rather than a plane.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_doubleSide, "DoubleSide", "Cameras will be able to look through the portal from both sides.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_lightBlending, "LightBlending", "Light from neighboring VisAreas will blend into the Portal.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_lightBlendValue, "LightBlendValue", "How much to blend lights from neighboring VisAreas.") - ->Attribute(AZ::Edit::Attributes::Max, 1.000000) - ->Attribute(AZ::Edit::Attributes::Min, 0.000000) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnChange) - ->DataElement( - AZ::Edit::UIHandlers::Default, &PortalConfiguration::m_vertices, "Vertices", "Points that make up the floor of the Portal.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &PortalConfiguration::OnVerticesChange) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; - } - } - } - - void EditorPortalComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(2) - ->Field("m_config", &EditorPortalComponent::m_config) - ->Field("ComponentMode", &EditorPortalComponent::m_componentModeDelegate) - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("Portal", "An area that describes a visibility portal between VisAreas.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Rendering") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/Portal.png") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/Portal.svg") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "http://docs.aws.amazon.com/console/lumberyard/userguide/portal-component") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorPortalComponent::m_config, "m_config", "No Description") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorPortalComponent::m_componentModeDelegate, "Component Mode", "Portal Component Mode") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("EditorPortalRequestBus") - ->Event("SetHeight", &EditorPortalRequestBus::Events::SetHeight) - ->Event("GetHeight", &EditorPortalRequestBus::Events::GetHeight) - ->VirtualProperty("Height", "GetHeight", "SetHeight") - - ->Event("SetDisplayFilled", &EditorPortalRequestBus::Events::SetDisplayFilled) - ->Event("GetDisplayFilled", &EditorPortalRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", "SetDisplayFilled") - - ->Event("SetAffectedBySun", &EditorPortalRequestBus::Events::SetAffectedBySun) - ->Event("GetAffectedBySun", &EditorPortalRequestBus::Events::GetAffectedBySun) - ->VirtualProperty("AffectedBySun", "GetAffectedBySun", "SetAffectedBySun") - - ->Event("SetViewDistRatio", &EditorPortalRequestBus::Events::SetViewDistRatio) - ->Event("GetViewDistRatio", &EditorPortalRequestBus::Events::GetViewDistRatio) - ->VirtualProperty("ViewDistRatio", "GetViewDistRatio", "SetViewDistRatio") - - ->Event("SetSkyOnly", &EditorPortalRequestBus::Events::SetSkyOnly) - ->Event("GetSkyOnly", &EditorPortalRequestBus::Events::GetSkyOnly) - ->VirtualProperty("SkyOnly", "GetSkyOnly", "SetSkyOnly") - - ->Event("SetOceanIsVisible", &EditorPortalRequestBus::Events::SetOceanIsVisible) - ->Event("GetOceanIsVisible", &EditorPortalRequestBus::Events::GetOceanIsVisible) - ->VirtualProperty("OceanIsVisible", "GetOceanIsVisible", "SetOceanIsVisible") - - ->Event("SetUseDeepness", &EditorPortalRequestBus::Events::SetUseDeepness) - ->Event("GetUseDeepness", &EditorPortalRequestBus::Events::GetUseDeepness) - ->VirtualProperty("UseDeepness", "GetUseDeepness", "SetUseDeepness") - - ->Event("SetDoubleSide", &EditorPortalRequestBus::Events::SetDoubleSide) - ->Event("GetDoubleSide", &EditorPortalRequestBus::Events::GetDoubleSide) - ->VirtualProperty("DoubleSide", "GetDoubleSide", "SetDoubleSide") - - ->Event("SetLightBlending", &EditorPortalRequestBus::Events::SetLightBlending) - ->Event("GetLightBlending", &EditorPortalRequestBus::Events::GetLightBlending) - ->VirtualProperty("LightBlending", "GetLightBlending", "SetLightBlending") - - ->Event("SetLightBlendValue", &EditorPortalRequestBus::Events::SetLightBlendValue) - ->Event("GetLightBlendValue", &EditorPortalRequestBus::Events::GetLightBlendValue) - ->VirtualProperty("LightBlendValue", "GetLightBlendValue", "SetLightBlendValue") - ; - - behaviorContext->Class()->RequestBus("EditorPortalRequestBus"); - } - - EditorPortalConfiguration::Reflect(context); - } - - void EditorPortalConfiguration::OnChange() - { - EditorPortalRequestBus::Event(m_entityId, &EditorPortalRequests::UpdatePortalObject); - } - - void EditorPortalConfiguration::OnVerticesChange() - { - EditorPortalRequestBus::Event(m_entityId, &EditorPortalRequests::UpdatePortalObject); - EditorPortalNotificationBus::Event(m_entityId, &EditorPortalNotifications::OnVerticesChangedInspector); - } - - void EditorPortalConfiguration::SetEntityId(const AZ::EntityId entityId) - { - m_entityId = entityId; - } - - EditorPortalComponent::~EditorPortalComponent() - { - if (m_area) - { - // reset the listener vis area in the unlucky case that we are deleting the - // vis area where the listener is currently in - // Audio: do we still need this? - GetIEditor()->Get3DEngine()->DeleteVisArea(m_area); - m_area = nullptr; - } - } - - void EditorPortalComponent::Activate() - { - Base::Activate(); - - const AZ::EntityId entityId = GetEntityId(); - m_config.SetEntityId(entityId); - - // NOTE: We create the vis-area here at activated, but destroy it in the destructor. - // We have to do this, otherwise the vis-area is not saved into the level. - // Unfortunately, at this time we cannot create the vis-areas at game runtime. - // This means that dynamic slices cannot effectively contain vis-areas until we fix the core rendering system to allow that. - - const auto visGUID = static_cast(entityId); - if(!m_area && GetIEditor()) - { - m_area = GetIEditor()->Get3DEngine()->CreateVisArea(visGUID); - } - - m_AZCachedWorldTransform = AZ::Transform::CreateIdentity(); - m_cryCachedWorldTransform = Matrix34::CreateIdentity(); - - m_componentModeDelegate.ConnectWithSingleComponentMode< - EditorPortalComponent, EditorPortalComponentMode>( - AZ::EntityComponentIdPair(entityId, GetId()), this); - - EditorPortalRequestBus::Handler::BusConnect(entityId); - AZ::FixedVerticesRequestBus::Handler::BusConnect(entityId); - AZ::TransformNotificationBus::Handler::BusConnect(entityId); - AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(entityId); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(entityId); - AzFramework::BoundsRequestBus::Handler::BusConnect(entityId); - - //Call OnTransformChanged manually to cache current transform since it won't be called - //automatically for us when the level starts up. - AZ::Transform worldTM; - AZ::TransformBus::EventResult(worldTM, entityId, &AZ::TransformBus::Events::GetWorldTM); - - //Use an identity transform for localTM because the - //OnTransformChanged impl for this class doesn't need it - OnTransformChanged(AZ::Transform::CreateIdentity(), worldTM); - } - - void EditorPortalComponent::Deactivate() - { - m_componentModeDelegate.Disconnect(); - - AzFramework::BoundsRequestBus::Handler::BusDisconnect(); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusDisconnect(GetEntityId()); - AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(GetEntityId()); - AZ::TransformNotificationBus::Handler::BusDisconnect(GetEntityId()); - AZ::FixedVerticesRequestBus::Handler::BusDisconnect(); - EditorPortalRequestBus::Handler::BusDisconnect(); - - Base::Deactivate(); - } - - void EditorPortalComponent::SetHeight(const float height) - { - m_config.m_height = height; - UpdatePortalObject(); - } - - float EditorPortalComponent::GetHeight() - { - return m_config.m_height; - } - - void EditorPortalComponent::SetDisplayFilled(const bool filled) - { - m_config.m_displayFilled = filled; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - void EditorPortalComponent::SetAffectedBySun(const bool affectedBySun) - { - m_config.m_affectedBySun = affectedBySun; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetAffectedBySun() - { - return m_config.m_affectedBySun; - } - - void EditorPortalComponent::SetViewDistRatio(const float viewDistRatio) - { - m_config.m_viewDistRatio = viewDistRatio; - UpdatePortalObject(); - } - - float EditorPortalComponent::GetViewDistRatio() - { - return m_config.m_viewDistRatio; - } - - void EditorPortalComponent::SetSkyOnly(const bool skyOnly) - { - m_config.m_skyOnly = skyOnly; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetSkyOnly() - { - return m_config.m_skyOnly; - } - - void EditorPortalComponent::SetOceanIsVisible(const bool oceanVisible) - { - m_config.m_oceanIsVisible = oceanVisible; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetOceanIsVisible() - { - return m_config.m_oceanIsVisible; - } - - void EditorPortalComponent::SetUseDeepness(const bool useDeepness) - { - m_config.m_useDeepness = useDeepness; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetUseDeepness() - { - return m_config.m_useDeepness; - } - - void EditorPortalComponent::SetDoubleSide(const bool doubleSided) - { - m_config.m_doubleSide = doubleSided; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetDoubleSide() - { - return m_config.m_doubleSide; - } - - void EditorPortalComponent::SetLightBlending(const bool lightBending) - { - m_config.m_lightBlending = lightBending; - UpdatePortalObject(); - } - - bool EditorPortalComponent::GetLightBlending() - { - return m_config.m_lightBlending; - } - - void EditorPortalComponent::SetLightBlendValue(const float lightBendAmount) - { - m_config.m_lightBlendValue = lightBendAmount; - UpdatePortalObject(); - } - - float EditorPortalComponent::GetLightBlendValue() - { - return m_config.m_lightBlendValue; - } - - bool EditorPortalComponent::GetVertex(const size_t index, AZ::Vector3& vertex) const - { - if (index < m_config.m_vertices.size()) - { - vertex = m_config.m_vertices[index]; - return true; - } - - return false; - } - - bool EditorPortalComponent::UpdateVertex(const size_t index, const AZ::Vector3& vertex) - { - if (index < m_config.m_vertices.size()) - { - m_config.m_vertices[index] = vertex; - return true; - } - - return false; - } - - /// Update the object runtime after changes to the Configuration. - /// Called by the default RequestBus SetXXX implementations, - /// and used to initially set up the object the first time the - /// Configuration are set. - void EditorPortalComponent::UpdatePortalObject() - { - if (m_area) - { - SVisAreaInfo info; - info.vAmbientColor = Vec3(ZERO); - info.bAffectedByOutLights = m_config.m_affectedBySun; - info.bSkyOnly = m_config.m_skyOnly; - info.fViewDistRatio = m_config.m_viewDistRatio; - info.bDoubleSide = m_config.m_doubleSide; - info.bUseDeepness = m_config.m_useDeepness; - info.bUseInIndoors = true; //Does not apply to Portals (Portals are only in VisAreas) - info.bOceanIsVisible = m_config.m_oceanIsVisible; - info.fPortalBlending = -1.0f; - - if (m_config.m_lightBlending) - { - info.fPortalBlending = m_config.m_lightBlendValue; - } - - AZStd::string name = AZStd::string("Portal_") + GetEntity()->GetName(); - - // Calculate scaled height - // Height exists separate from plane points but we still want to scale it with the transform - info.fHeight = m_config.m_height; - - /* - We have to derive at least 3 points and pass them to the vis area system - For now that means getting the 4 points of the bottom face of the box. - - If we want to send *all* points of a shape the vis system we need to make sure - that Height is 0; otherwise it'll extend the AABB of the area upwards. - */ - - //Convert to Cry vectors and apply the transform to the given points - AZStd::fixed_vector verts(4); - for (AZ::u32 i = 0; i < verts.size(); ++i) - { - verts[i] = AZVec3ToLYVec3(m_config.m_vertices[i]); - verts[i] = m_cryCachedWorldTransform.TransformPoint(verts[i]); - } - - GetIEditor()->Get3DEngine()->UpdateVisArea(m_area, &verts[0], verts.size(), name.c_str(), info, true); - - AzFramework::EntityBoundsUnionRequestBus::Broadcast( - &AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); - } - } - - void EditorPortalComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) - { - //Cache the transform so that we don't have to retrieve it every time UpdatePortalObject is called - m_AZCachedWorldTransform = world; - m_cryCachedWorldTransform = AZTransformToLYTransform(m_AZCachedWorldTransform); - - UpdatePortalObject(); - } - - struct PortalQuadVertices - { - AZ::Vector3 floorLeftFront; - AZ::Vector3 floorRightFront; - AZ::Vector3 floorLeftBack; - AZ::Vector3 floorRightBack; - - AZ::Vector3 quadUpperLeftFront; - AZ::Vector3 quadUpperRightFront; - AZ::Vector3 quadUpperLeftBack; - AZ::Vector3 quadUpperRightBack; - - AZ::Vector3 portalUpperLeftFront; - AZ::Vector3 portalUpperRightFront; - AZ::Vector3 portalUpperLeftBack; - AZ::Vector3 portalUpperRightBack; - }; - - PortalQuadVertices EditorPortalComponent::CalculatePortalQuadVertices(VertTranslation vertTranslation) - { - PortalQuadVertices pqv; - - //Untransformed quad corners - const AZ::Vector3 lowerLeftFront = m_config.m_vertices[0]; - const AZ::Vector3 lowerRightFront = m_config.m_vertices[1]; - const AZ::Vector3 lowerLeftBack = m_config.m_vertices[3]; - const AZ::Vector3 lowerRightBack = m_config.m_vertices[2]; - - //Need to calculate the height of the quad after transformation - const AZ::u32 quadPointCount = 4; - AZ::Vector3 transformedQuadPoints[quadPointCount]; - - transformedQuadPoints[0] = m_AZCachedWorldTransform.TransformPoint(lowerLeftFront); - transformedQuadPoints[1] = m_AZCachedWorldTransform.TransformPoint(lowerRightFront); - transformedQuadPoints[2] = m_AZCachedWorldTransform.TransformPoint(lowerLeftBack); - transformedQuadPoints[3] = m_AZCachedWorldTransform.TransformPoint(lowerRightBack); - - const AZ::Vector3 translation = m_AZCachedWorldTransform.GetTranslation(); - - float minHeight = FLT_MAX; - float maxHeight = FLT_MIN; - - for (auto& transformedQuadPoint : transformedQuadPoints) - { - // remove translation from quad points so we can use them with the DisplayContext's usage of the transform - if (vertTranslation == VertTranslation::Remove) - { - transformedQuadPoint -= translation; - } - - const float height = transformedQuadPoint.GetZ(); - if (height < minHeight) - { - minHeight = height; - } - if (height > maxHeight) - { - maxHeight = height; - } - } - - pqv.floorLeftFront = AZ::Vector3(transformedQuadPoints[0].GetX(), transformedQuadPoints[0].GetY(), minHeight); - pqv.floorRightFront = AZ::Vector3(transformedQuadPoints[1].GetX(), transformedQuadPoints[1].GetY(), minHeight); - pqv.floorLeftBack = AZ::Vector3(transformedQuadPoints[2].GetX(), transformedQuadPoints[2].GetY(), minHeight); - pqv.floorRightBack = AZ::Vector3(transformedQuadPoints[3].GetX(), transformedQuadPoints[3].GetY(), minHeight); - - pqv.quadUpperLeftFront = AZ::Vector3(transformedQuadPoints[0].GetX(), transformedQuadPoints[0].GetY(), maxHeight); - pqv.quadUpperRightFront = AZ::Vector3(transformedQuadPoints[1].GetX(), transformedQuadPoints[1].GetY(), maxHeight); - pqv.quadUpperLeftBack = AZ::Vector3(transformedQuadPoints[2].GetX(), transformedQuadPoints[2].GetY(), maxHeight); - pqv.quadUpperRightBack = AZ::Vector3(transformedQuadPoints[3].GetX(), transformedQuadPoints[3].GetY(), maxHeight); - - pqv.portalUpperLeftFront = AZ::Vector3(transformedQuadPoints[0].GetX(), transformedQuadPoints[0].GetY(), maxHeight + m_config.m_height); - pqv.portalUpperRightFront = AZ::Vector3(transformedQuadPoints[1].GetX(), transformedQuadPoints[1].GetY(), maxHeight + m_config.m_height); - pqv.portalUpperLeftBack = AZ::Vector3(transformedQuadPoints[2].GetX(), transformedQuadPoints[2].GetY(), maxHeight + m_config.m_height); - pqv.portalUpperRightBack = AZ::Vector3(transformedQuadPoints[3].GetX(), transformedQuadPoints[3].GetY(), maxHeight + m_config.m_height); - - return pqv; - } - - void EditorPortalComponent::DisplayEntityViewport( - [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) - { - /* - IMPORTANT NOTE: This method may seem very complicated but it is an accurate visualization of - how portals actually work. The legacy visualization used with the legacy portal entity is - very misleading! - - Portals always exist as a quad but if the quad becomes non-planar, from rotation or in the legacy - system from a point being pulled up or down, the volume changes in a non-obvious way. Instead of portal - existing as the shape defined by 4 points and extruded upwards, the portal actually remains planar. - Any height difference that you add by making the shape non-planar is just applied to the height of the volume. - - If this is confusing, please actually look at the visualization created by this method. Make sure - that you rotate the portal in many weird contorted ways and examine how the visualization reacts. - The portal volume is always going to be a box rotated on only X and Y axes that stretches up along the Z axis. - - Important note on the complexity of this method: - We cannot directly visualize the OBB of the portal with an AABB that we then transform. The OBB that's mentioned - here is best imagined as the top plane being all points of the quad pulled up to the height of the highest quad's vert - and the bottom plane being all points of the quad pulled down to the height of the lowest quad's vert. Trying to - create an AABB from these points won't produce the correct visualization under complex rotations as the Min and Max - of the AABB will either only encompass part of the bounding volume or be too large. - */ - - const PortalQuadVertices pqv = CalculatePortalQuadVertices(VertTranslation::Remove); - - //Draw the outline of the OBB of the Portal's quad - AZ::Color color(0.000f, 1.0f, 0.000f, 1.0f); - debugDisplay.SetColor(AZ::Vector4(color.GetR(), color.GetG(), color.GetB(), 1.f)); - - //Remove all rotation from the transform - const AZ::Quaternion rotation = AZ::Quaternion::CreateIdentity(); - - AZ::Transform worldTMOnlyZRot = m_AZCachedWorldTransform; - worldTMOnlyZRot.SetRotation(rotation); - - debugDisplay.PushMatrix(worldTMOnlyZRot); - - //Draw the outline of the OBB of the portal quad - - //Bottom - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.floorRightFront); - debugDisplay.DrawLine(pqv.floorRightFront, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.floorLeftBack); - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorLeftFront); - //Top - debugDisplay.DrawLine(pqv.quadUpperLeftFront, pqv.quadUpperRightFront); - debugDisplay.DrawLine(pqv.quadUpperRightFront, pqv.quadUpperRightBack); - debugDisplay.DrawLine(pqv.quadUpperRightBack, pqv.quadUpperLeftBack); - debugDisplay.DrawLine(pqv.quadUpperLeftBack, pqv.quadUpperLeftFront); - //Left - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.quadUpperLeftFront); - debugDisplay.DrawLine(pqv.quadUpperLeftFront, pqv.quadUpperLeftBack); - debugDisplay.DrawLine(pqv.quadUpperLeftBack, pqv.floorLeftBack); - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorLeftFront); - //Right - debugDisplay.DrawLine(pqv.floorRightFront, pqv.quadUpperRightFront); - debugDisplay.DrawLine(pqv.quadUpperRightFront, pqv.quadUpperRightBack); - debugDisplay.DrawLine(pqv.quadUpperRightBack, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.floorRightFront); - //Front - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.floorRightFront); - debugDisplay.DrawLine(pqv.floorRightFront, pqv.quadUpperRightFront); - debugDisplay.DrawLine(pqv.quadUpperRightFront, pqv.quadUpperLeftFront); - debugDisplay.DrawLine(pqv.quadUpperLeftFront, pqv.floorLeftFront); - //Back - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.quadUpperRightBack); - debugDisplay.DrawLine(pqv.quadUpperRightBack, pqv.quadUpperLeftBack); - debugDisplay.DrawLine(pqv.quadUpperLeftBack, pqv.floorLeftBack); - - //Now draw the entire portal volume (Previous OBB + extra height) - if (m_config.m_displayFilled) - { - //Draw whole portal with less alpha - debugDisplay.SetColor(AZ::Vector4(color.GetR(), color.GetG(), color.GetB(), 0.1f)); - - //Draw both winding orders for quads so they appear solid from all angles - //Not drawing boxes because the corners of the quad may not be hit if the bounds are rotated oddly - - //Bottom - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.floorRightFront, pqv.floorRightBack, pqv.floorLeftBack); - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.floorLeftBack, pqv.floorRightBack, pqv.floorRightFront); - //Top - debugDisplay.DrawQuad(pqv.portalUpperLeftFront, pqv.portalUpperRightFront, pqv.portalUpperRightBack, pqv.portalUpperLeftBack); - debugDisplay.DrawQuad(pqv.portalUpperLeftFront, pqv.portalUpperLeftBack, pqv.portalUpperRightBack, pqv.portalUpperRightFront); - //Left - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.portalUpperLeftFront, pqv.portalUpperLeftBack, pqv.floorLeftBack); - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.floorLeftBack, pqv.portalUpperLeftBack, pqv.portalUpperLeftFront); - //Right - debugDisplay.DrawQuad(pqv.floorRightFront, pqv.portalUpperRightFront, pqv.portalUpperRightBack, pqv.floorRightBack); - debugDisplay.DrawQuad(pqv.floorRightFront, pqv.floorRightBack, pqv.portalUpperRightBack, pqv.portalUpperRightFront); - //Front - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.floorRightFront, pqv.portalUpperRightFront, pqv.portalUpperLeftFront); - debugDisplay.DrawQuad(pqv.floorLeftFront, pqv.portalUpperLeftFront, pqv.portalUpperRightFront, pqv.floorRightFront); - //Back - debugDisplay.DrawQuad(pqv.floorLeftBack, pqv.floorRightBack, pqv.portalUpperRightBack, pqv.portalUpperLeftBack); - debugDisplay.DrawQuad(pqv.floorLeftBack, pqv.portalUpperLeftBack, pqv.portalUpperRightBack, pqv.floorRightBack); - } - else - { - //Bottom - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.floorRightFront); - debugDisplay.DrawLine(pqv.floorRightFront, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.floorLeftBack); - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorLeftFront); - //Top - debugDisplay.DrawLine(pqv.portalUpperLeftFront, pqv.portalUpperRightFront); - debugDisplay.DrawLine(pqv.portalUpperRightFront, pqv.portalUpperRightBack); - debugDisplay.DrawLine(pqv.portalUpperRightBack, pqv.portalUpperLeftBack); - debugDisplay.DrawLine(pqv.portalUpperLeftBack, pqv.portalUpperLeftFront); - //Left - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.portalUpperLeftFront); - debugDisplay.DrawLine(pqv.portalUpperLeftFront, pqv.portalUpperLeftBack); - debugDisplay.DrawLine(pqv.portalUpperLeftBack, pqv.floorLeftBack); - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorLeftFront); - //Right - debugDisplay.DrawLine(pqv.floorRightFront, pqv.portalUpperRightFront); - debugDisplay.DrawLine(pqv.portalUpperRightFront, pqv.portalUpperRightBack); - debugDisplay.DrawLine(pqv.portalUpperRightBack, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.floorRightFront); - //Front - debugDisplay.DrawLine(pqv.floorLeftFront, pqv.floorRightFront); - debugDisplay.DrawLine(pqv.floorRightFront, pqv.portalUpperRightFront); - debugDisplay.DrawLine(pqv.portalUpperRightFront, pqv.portalUpperLeftFront); - debugDisplay.DrawLine(pqv.portalUpperLeftFront, pqv.floorLeftFront); - //Back - debugDisplay.DrawLine(pqv.floorLeftBack, pqv.floorRightBack); - debugDisplay.DrawLine(pqv.floorRightBack, pqv.portalUpperRightBack); - debugDisplay.DrawLine(pqv.portalUpperRightBack, pqv.portalUpperLeftBack); - debugDisplay.DrawLine(pqv.portalUpperLeftBack, pqv.floorLeftBack); - } - - if (m_componentModeDelegate.AddedToComponentMode()) - { - AzToolsFramework::VertexContainerDisplay::DisplayVertexContainerIndices( - debugDisplay, AzToolsFramework::FixedVerticesArray(m_config.m_vertices), - GetWorldTM(), AZ::Vector3::CreateOne(), IsSelected()); - } - - debugDisplay.PopMatrix(); - } - - void EditorPortalComponent::BuildGameEntity(AZ::Entity* gameEntity) - { - gameEntity->CreateComponent(m_config); - } - - AZ::Aabb EditorPortalComponent::GetEditorSelectionBoundsViewport(const AzFramework::ViewportInfo& /*viewportInfo*/) - { - const PortalQuadVertices pqv = CalculatePortalQuadVertices(VertTranslation::Keep); - - AZ::Aabb bbox = AZ::Aabb::CreateNull(); - bbox.AddPoint(pqv.floorLeftFront); - bbox.AddPoint(pqv.floorRightFront); - bbox.AddPoint(pqv.floorLeftBack); - bbox.AddPoint(pqv.floorRightBack); - bbox.AddPoint(pqv.portalUpperLeftFront); - return bbox; - } - - bool EditorPortalComponent::EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) - { - float t; - float intermediateT = FLT_MAX; - - const PortalQuadVertices pqv = CalculatePortalQuadVertices(VertTranslation::Keep); - - //Count each quad for intersection hits, two hits implies we are intersecting the prism from outside of it (or from too far) - AZ::u8 hits = 0; - - //Bottom - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.floorLeftFront, pqv.floorRightFront, pqv.floorRightBack, pqv.floorLeftBack, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - //Top - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.portalUpperLeftFront, pqv.portalUpperRightFront, pqv.portalUpperRightBack, pqv.portalUpperLeftBack, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - - //Left - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.floorLeftFront, pqv.portalUpperLeftFront, pqv.portalUpperLeftBack, pqv.floorLeftBack, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - //Right - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.floorRightFront, pqv.portalUpperRightFront, pqv.portalUpperRightBack, pqv.floorRightBack, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - //Front - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.floorLeftFront, pqv.floorRightFront, pqv.portalUpperRightFront, pqv.portalUpperLeftFront, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - //Back - if (AZ::Intersect::IntersectRayQuad(src, dir, pqv.floorLeftBack, pqv.floorRightBack, pqv.portalUpperRightBack, pqv.portalUpperLeftBack, t)) - { - ++hits; - intermediateT = AZStd::GetMin(t, intermediateT); - } - - if (hits > 0) - { - distance = intermediateT; - } - return hits >= 2; - } - - AZ::Aabb EditorPortalComponent::GetWorldBounds() - { - return GetLocalBounds().GetTransformedAabb(m_AZCachedWorldTransform); - } - - AZ::Aabb EditorPortalComponent::GetLocalBounds() - { - AZ::Aabb bbox = AZ::Aabb::CreateNull(); - for (const auto& vertex : m_config.m_vertices) - { - bbox.AddPoint(vertex); - } - return bbox; - } -} //namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorPortalComponent.h b/Gems/Visibility/Code/Source/EditorPortalComponent.h deleted file mode 100644 index a8e00b9698..0000000000 --- a/Gems/Visibility/Code/Source/EditorPortalComponent.h +++ /dev/null @@ -1,148 +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 -#include -#include -#include -#include -#include - -#include "PortalComponent.h" -#include "EditorPortalComponentBus.h" - -namespace Visibility -{ - class EditorPortalComponent; - struct PortalQuadVertices; - - class EditorPortalConfiguration - : public PortalConfiguration - { - public: - AZ_TYPE_INFO_LEGACY(EditorPortalConfiguration, "{C9F99449-7A77-50C4-9ED3-D69B923BFDBD}", PortalConfiguration); - AZ_CLASS_ALLOCATOR(EditorPortalConfiguration, AZ::SystemAllocator,0); - - static void Reflect(AZ::ReflectContext* context); - - void OnChange() override; - void OnVerticesChange() override; - - void SetEntityId(AZ::EntityId entityId); - - private: - AZ::EntityId m_entityId; - }; - - class EditorPortalComponent - : public AzToolsFramework::Components::EditorComponentBase - , private EditorPortalRequestBus::Handler - , private AZ::FixedVerticesRequestBus::Handler - , private AzFramework::EntityDebugDisplayEventBus::Handler - , private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler - , public AZ::TransformNotificationBus::Handler - , public AzFramework::BoundsRequestBus::Handler - { - friend class EditorPortalConfiguration; - - using Base = AzToolsFramework::Components::EditorComponentBase; - - public: - AZ_COMPONENT(EditorPortalComponent, "{64525CDD-7DD4-5CEF-B545-559127DC834E}", AzToolsFramework::Components::EditorComponentBase); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - static void Reflect(AZ::ReflectContext* context); - - EditorPortalComponent() = default; - EditorPortalComponent(const EditorPortalComponent&) = delete; - EditorPortalComponent& operator=(const EditorPortalComponent&) = delete; - ~EditorPortalComponent() override; - - // EditorComponentBase overrides ... - void Activate() override; - void Deactivate() override; - void BuildGameEntity(AZ::Entity* gameEntity) override; - - // TransformNotificationBus overrides ... - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // EditorComponentSelectionRequestsBus overrides ... - AZ::Aabb GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& viewportInfo) override; - bool EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) override; - bool SupportsEditorRayIntersect() override { return true; } - - // PortalRequestBus overrides ... - void SetHeight(float height) override; - float GetHeight() override; - void SetDisplayFilled(bool filled) override; - bool GetDisplayFilled() override; - void SetAffectedBySun(bool affectedBySun) override; - bool GetAffectedBySun() override; - void SetViewDistRatio(float viewDistRatio) override; - float GetViewDistRatio() override; - void SetSkyOnly(bool skyOnly) override; - bool GetSkyOnly() override; - void SetOceanIsVisible(bool oceanVisible) override; - bool GetOceanIsVisible() override; - void SetUseDeepness(bool useDeepness) override; - bool GetUseDeepness() override; - void SetDoubleSide(bool doubleSided) override; - bool GetDoubleSide() override; - void SetLightBlending(bool lightBending) override; - bool GetLightBlending() override; - void SetLightBlendValue(float lightBendAmount) override; - float GetLightBlendValue() override; - bool GetVertex(size_t index, AZ::Vector3& vertex) const override; - bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override; - size_t Size() const override { return m_config.m_vertices.size(); } - void UpdatePortalObject() override; - - // EntityDebugDisplayBus overrides ... - void DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; - - // BoundsRequestBus overrides ... - AZ::Aabb GetWorldBounds() override; - AZ::Aabb GetLocalBounds() override; - - private: - enum class VertTranslation - { - Keep, - Remove - }; - - PortalQuadVertices CalculatePortalQuadVertices(VertTranslation vertTranslation); - - // Reflected members - EditorPortalConfiguration m_config; - - using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate; - ComponentModeDelegate m_componentModeDelegate; ///< Responsible for detecting ComponentMode activation - ///< and creating a concrete ComponentMode. - - AZ::Transform m_AZCachedWorldTransform; - Matrix44 m_cryCachedWorldTransform; - IVisArea* m_area = nullptr; - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorPortalComponentMode.cpp b/Gems/Visibility/Code/Source/EditorPortalComponentMode.cpp deleted file mode 100644 index 5d9b089c65..0000000000 --- a/Gems/Visibility/Code/Source/EditorPortalComponentMode.cpp +++ /dev/null @@ -1,85 +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 "Visibility_precompiled.h" -#include "EditorPortalComponentMode.h" - -#include - -namespace Visibility -{ - AZ_CLASS_ALLOCATOR_IMPL(EditorPortalComponentMode, AZ::SystemAllocator, 0) - - EditorPortalComponentMode::EditorPortalComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType) - : EditorBaseComponentMode(entityComponentIdPair, componentType) - { - CreateManipulators(); - - AZ::TransformNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - EditorPortalNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - } - - EditorPortalComponentMode::~EditorPortalComponentMode() - { - EditorPortalNotificationBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - - m_vertexSelection.Destroy(); - } - - void EditorPortalComponentMode::CreateManipulators() - { - using namespace AzToolsFramework; - - m_vertexSelection.Create( - AZ::EntityComponentIdPair(GetEntityId(), GetComponentId()), g_mainManipulatorManagerId, - AZStd::make_unique(), - TranslationManipulators::Dimensions::Three, - ConfigureTranslationManipulatorAppearance3d); - - m_vertexSelection.SetVertexPositionsUpdatedCallback([this]() - { - EditorPortalRequestBus::Event( - GetEntityId(), &EditorPortalRequests::UpdatePortalObject); - }); - } - - void EditorPortalComponentMode::OnTransformChanged( - const AZ::Transform& /*local*/, const AZ::Transform& world) - { - m_vertexSelection.RefreshSpace(world); - } - - void EditorPortalComponentMode::OnVerticesChangedInspector() - { - m_vertexSelection.RefreshLocal(); - } - - void EditorPortalComponentMode::Refresh() - { - // destroy and recreate manipulators when container is modified (vertices are added or removed) - m_vertexSelection.Destroy(); - CreateManipulators(); - } - - AZStd::vector EditorPortalComponentMode::PopulateActionsImpl() - { - return m_vertexSelection.ActionOverrides(); - } - - bool EditorPortalComponentMode::HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) - { - return m_vertexSelection.HandleMouse(mouseInteraction); - } -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorPortalComponentMode.h b/Gems/Visibility/Code/Source/EditorPortalComponentMode.h deleted file mode 100644 index 633c3a1ba8..0000000000 --- a/Gems/Visibility/Code/Source/EditorPortalComponentMode.h +++ /dev/null @@ -1,53 +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 -#include - -#include "EditorPortalComponentBus.h" - -namespace Visibility -{ - class EditorPortalComponentMode - : public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode - , private AZ::TransformNotificationBus::Handler - , private EditorPortalNotificationBus::Handler - { - public: - AZ_CLASS_ALLOCATOR_DECL - - EditorPortalComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType); - ~EditorPortalComponentMode(); - - private: - // EditorBaseComponentMode - void Refresh() override; - AZStd::vector PopulateActionsImpl() override; - bool HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; - - // Manipulator handling - void CreateManipulators(); - - // TransformNotificationBus - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // EditorPortalNotificationBus - void OnVerticesChangedInspector() override; - - AzToolsFramework::EditorVertexSelectionFixed m_vertexSelection; ///< Handles all manipulator interactions with vertices. - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorVisAreaComponent.cpp b/Gems/Visibility/Code/Source/EditorVisAreaComponent.cpp deleted file mode 100644 index 48045d9023..0000000000 --- a/Gems/Visibility/Code/Source/EditorVisAreaComponent.cpp +++ /dev/null @@ -1,629 +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 "Visibility_precompiled.h" -#include "EditorVisAreaComponent.h" -#include "EditorVisAreaComponentMode.h" - -#include -#include -#include -#include -#include - -// Include files needed for writing DisplayEntity functions that access the DisplayContext directly. -#include - -#include "MathConversion.h" - -namespace Visibility -{ - /*static*/ AZ::Color EditorVisAreaComponent::s_visAreaColor = AZ::Color(1.0f, 0.5f, 0.0f, 1.0f); - - void EditorVisAreaComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("EditorVisAreaService", 0x4507d2ae)); - provided.push_back(AZ_CRC("VisAreaService", 0x0c063fb9)); - provided.push_back(AZ_CRC("VariableVertexContainerService", 0x70c58740)); - provided.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorVisAreaComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires) - { - requires.push_back(AZ_CRC("TransformService", 0x8ee22c50)); - } - - void EditorVisAreaComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("VariableVertexContainerService", 0x70c58740)); - incompatible.push_back(AZ_CRC("FixedVertexContainerService", 0x83f1bbf2)); - } - - void EditorVisAreaConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1); - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("VisArea Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true); - - editContext->Class("VisArea Configuration", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_height, "Height", "How tall the VisArea is.") - ->Attribute(AZ::Edit::Attributes::Max, 100.0f) - ->Attribute(AZ::Edit::Attributes::Min, 0.0f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeHeight) - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_displayFilled, "DisplayFilled", "Display the VisArea as a filled volume.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeDisplayFilled) - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_affectedBySun, "AffectedBySun", "Allows sunlight to affect objects inside the VisArea.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeAffectedBySun) - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_viewDistRatio, "ViewDistRatio", "Specifies how far the VisArea is rendered.") - ->Attribute(AZ::Edit::Attributes::Max, 100.0f) - ->Attribute(AZ::Edit::Attributes::Min, 0.0f) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeViewDistRatio) - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_oceanIsVisible, "OceanIsVisible", "Ocean will be visible when looking outside the VisArea.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeOceanIsVisible) - // note: This will not work as expected. See Activate where we set the callbacks on the vertex container directly - ->DataElement(AZ::Edit::UIHandlers::Default, &VisAreaConfiguration::m_vertexContainer, "Vertices", "Points that make up the floor of the VisArea.") - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &VisAreaConfiguration::ChangeVertexContainer) - ; - } - } - } - - void EditorVisAreaComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(2) - ->Field("m_config", &EditorVisAreaComponent::m_config) - ->Field("ComponentMode", &EditorVisAreaComponent::m_componentModeDelegate) - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class("VisArea", "An area where only objects inside the area will be visible.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Rendering") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/VisArea.png") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/VisArea.svg") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "http://docs.aws.amazon.com/console/lumberyard/userguide/vis-area-component") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorVisAreaComponent::m_config, "m_config", "No Description") - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorVisAreaComponent::m_componentModeDelegate, "Component Mode", "VisArea Component Mode") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ; - } - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("EditorVisAreaComponentRequestBus") - ->Event("SetHeight", &EditorVisAreaComponentRequestBus::Events::SetHeight) - ->Event("GetHeight", &EditorVisAreaComponentRequestBus::Events::GetHeight) - ->VirtualProperty("Height", "GetHeight", "SetHeight") - - ->Event("SetDisplayFilled", &EditorVisAreaComponentRequestBus::Events::SetDisplayFilled) - ->Event("GetDisplayFilled", &EditorVisAreaComponentRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", "SetDisplayFilled") - - ->Event("SetAffectedBySun", &EditorVisAreaComponentRequestBus::Events::SetAffectedBySun) - ->Event("GetAffectedBySun", &EditorVisAreaComponentRequestBus::Events::GetAffectedBySun) - ->VirtualProperty("AffectedBySun", "GetAffectedBySun", "SetAffectedBySun") - - ->Event("SetViewDistRatio", &EditorVisAreaComponentRequestBus::Events::SetViewDistRatio) - ->Event("GetViewDistRatio", &EditorVisAreaComponentRequestBus::Events::GetViewDistRatio) - ->VirtualProperty("ViewDistRatio", "GetViewDistRatio", "SetViewDistRatio") - - ->Event("SetOceanIsVisible", &EditorVisAreaComponentRequestBus::Events::SetOceanIsVisible) - ->Event("GetOceanIsVisible", &EditorVisAreaComponentRequestBus::Events::GetOceanIsVisible) - ->VirtualProperty("OceanIsVisible", "GetOceanIsVisible", "SetOceanIsVisible") - ; - - behaviorContext->Class()->RequestBus("EditorVisAreaComponentRequestBus"); - } - - EditorVisAreaConfiguration::Reflect(context); - } - - void EditorVisAreaConfiguration::ChangeHeight() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::ChangeDisplayFilled() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::ChangeAffectedBySun() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::ChangeViewDistRatio() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::ChangeOceanIsVisible() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::ChangeVertexContainer() - { - EditorVisAreaComponentRequestBus::Event( - m_entityId, &EditorVisAreaComponentRequests::UpdateVisAreaObject); - } - - void EditorVisAreaConfiguration::SetEntityId(const AZ::EntityId entityId) - { - m_entityId = entityId; - } - - EditorVisAreaComponent::~EditorVisAreaComponent() - { - if (m_area) - { - // Reset the listener vis area in the unlucky case that we are deleting the - // vis area where the listener is currently in - GetIEditor()->Get3DEngine()->DeleteVisArea(m_area); - m_area = nullptr; - } - } - - void EditorVisAreaComponent::Activate() - { - Base::Activate(); - - const AZ::EntityId entityId = GetEntityId(); - - // NOTE: We create the vis-area here at activated, but destroy it in the destructor. - // We have to do this, otherwise the vis-area is not saved into the level. - // Unfortunately, at this time we cannot create the vis-areas at game runtime. - // This means that dynamic slices cannot effectively contain vis areas until we fix the core rendering system to allow that. - - const auto visGUID = AZ::u64(entityId); - if(!m_area && GetIEditor()) - { - m_area = GetIEditor()->Get3DEngine()->CreateVisArea(visGUID); - } - - m_componentModeDelegate.ConnectWithSingleComponentMode< - EditorVisAreaComponent, EditorVisAreaComponentMode>( - AZ::EntityComponentIdPair(entityId, GetId()), this); - - // give default values to the vertices if needed - if (m_config.m_vertexContainer.Size() == 0) - { - m_config.m_vertexContainer.AddVertex(AZ::Vector3(-1.0f, -1.0f, 0.0f)); - m_config.m_vertexContainer.AddVertex(AZ::Vector3(+1.0f, -1.0f, 0.0f)); - m_config.m_vertexContainer.AddVertex(AZ::Vector3(+1.0f, +1.0f, 0.0f)); - m_config.m_vertexContainer.AddVertex(AZ::Vector3(-1.0f, +1.0f, 0.0f)); - } - - const auto vertexAdded = [this](size_t vertIndex) - { - EditorVisAreaComponentNotificationBus::Event( - GetEntityId(), &EditorVisAreaComponentNotifications::OnVertexAdded, vertIndex); - - UpdateVisAreaObject(); - }; - - const auto vertexRemoved = [this](size_t vertIndex) - { - EditorVisAreaComponentNotificationBus::Event( - GetEntityId(), &EditorVisAreaComponentNotifications::OnVertexRemoved, vertIndex); - - UpdateVisAreaObject(); - }; - - const auto vertexChanged = [this](size_t vertIndex) - { - EditorVisAreaComponentNotificationBus::Event( - GetEntityId(), &EditorVisAreaComponentNotifications::OnVertexUpdated, vertIndex); - - UpdateVisAreaObject(); - }; - - const auto verticesSet = [this]() - { - EditorVisAreaComponentNotificationBus::Event( - GetEntityId(), &EditorVisAreaComponentNotifications::OnVerticesSet, - m_config.m_vertexContainer.GetVertices()); - - UpdateVisAreaObject(); - }; - - const auto verticesCleared = [this]() - { - EditorVisAreaComponentNotificationBus::Event( - GetEntityId(), &EditorVisAreaComponentNotifications::OnVerticesCleared); - - UpdateVisAreaObject(); - }; - - m_config.m_vertexContainer.SetCallbacks( - vertexAdded, vertexRemoved, vertexChanged, - verticesSet, verticesCleared); - - m_config.SetEntityId(entityId); - - AZ::TransformBus::EventResult( - m_currentWorldTransform, GetEntityId(), &AZ::TransformBus::Events::GetWorldTM); - - // make the initial vis area with the data we just parsed - UpdateVisAreaObject(); - - EditorVisAreaComponentRequestBus::Handler::BusConnect(entityId); - AZ::VariableVerticesRequestBus::Handler::BusConnect(entityId); - AZ::FixedVerticesRequestBus::Handler::BusConnect(entityId); - AZ::TransformNotificationBus::Handler::BusConnect(entityId); - AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(entityId); - AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusConnect(); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusConnect(entityId); - AzFramework::BoundsRequestBus::Handler::BusConnect(entityId); - } - - void EditorVisAreaComponent::Deactivate() - { - m_componentModeDelegate.Disconnect(); - - AzFramework::BoundsRequestBus::Handler::BusDisconnect(); - AzToolsFramework::EditorComponentSelectionRequestsBus::Handler::BusDisconnect(); - AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); - AzToolsFramework::EditorEntityInfoNotificationBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - AZ::FixedVerticesRequestBus::Handler::BusDisconnect(); - AZ::VariableVerticesRequestBus::Handler::BusDisconnect(); - EditorVisAreaComponentRequestBus::Handler::BusDisconnect(); - - Base::Deactivate(); - } - - void EditorVisAreaComponent::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world) - { - m_currentWorldTransform = world; - UpdateVisAreaObject(); - } - - /// Apply the component's settings to the underlying vis area - void EditorVisAreaComponent::UpdateVisAreaObject() - { - if (m_area) - { - std::vector points; - - const AZStd::vector& vertices = m_config.m_vertexContainer.GetVertices(); - const size_t vertexCount = vertices.size(); - - if (vertexCount > 3) - { - const Matrix34& wtm = AZTransformToLYTransform(GetWorldTM()); - points.resize(vertexCount); - for (size_t i = 0; i < vertexCount; i++) - { - points[i] = wtm.TransformPoint(AZVec3ToLYVec3(vertices[i])); - } - - SVisAreaInfo info; - info.fHeight = GetHeight(); - info.bAffectedByOutLights = m_config.m_affectedBySun; - info.fViewDistRatio = m_config.m_viewDistRatio; - info.bOceanIsVisible = m_config.m_oceanIsVisible; - - //Unconfigurable; these values are used by other area types - //We set them just so that debugging later it's clear that these - //aren't being used because this is a VisArea. - info.fPortalBlending = -1; - info.bDoubleSide = true; - info.bUseDeepness = false; - info.bUseInIndoors = false; - - const AZStd::string name = AZStd::string("vis-area_") + GetEntity()->GetName(); - - GetIEditor()->Get3DEngine()->UpdateVisArea(m_area, &points[0], points.size(), name.c_str(), info, true); - - AzFramework::EntityBoundsUnionRequestBus::Broadcast( - &AzFramework::EntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); - } - } - } - - void EditorVisAreaComponent::SetHeight(const float value) - { - m_config.m_height = value; - UpdateVisAreaObject(); - } - - float EditorVisAreaComponent::GetHeight() - { - return m_config.m_height; - } - - void EditorVisAreaComponent::SetDisplayFilled(const bool value) - { - m_config.m_displayFilled = value; - UpdateVisAreaObject(); - } - - bool EditorVisAreaComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - void EditorVisAreaComponent::SetAffectedBySun(const bool value) - { - m_config.m_affectedBySun = value; - UpdateVisAreaObject(); - } - - bool EditorVisAreaComponent::GetAffectedBySun() - { - return m_config.m_affectedBySun; - } - - void EditorVisAreaComponent::SetViewDistRatio(const float value) - { - m_config.m_viewDistRatio = value; - UpdateVisAreaObject(); - } - - float EditorVisAreaComponent::GetViewDistRatio() - { - return m_config.m_viewDistRatio; - } - - void EditorVisAreaComponent::SetOceanIsVisible(const bool value) - { - m_config.m_oceanIsVisible = value; - UpdateVisAreaObject(); - } - - bool EditorVisAreaComponent::GetOceanIsVisible() - { - return m_config.m_oceanIsVisible; - } - - bool EditorVisAreaComponent::GetVertex(size_t index, AZ::Vector3& vertex) const - { - return m_config.m_vertexContainer.GetVertex(index, vertex); - } - - void EditorVisAreaComponent::AddVertex(const AZ::Vector3& vertex) - { - m_config.m_vertexContainer.AddVertex(vertex); - UpdateVisAreaObject(); - } - - bool EditorVisAreaComponent::UpdateVertex(size_t index, const AZ::Vector3& vertex) - { - if (m_config.m_vertexContainer.UpdateVertex(index, vertex)) - { - UpdateVisAreaObject(); - return true; - } - - return false; - } - - bool EditorVisAreaComponent::InsertVertex(size_t index, const AZ::Vector3& vertex) - { - if (m_config.m_vertexContainer.InsertVertex(index, vertex)) - { - UpdateVisAreaObject(); - return true; - } - - return false; - } - - bool EditorVisAreaComponent::RemoveVertex(size_t index) - { - if (m_config.m_vertexContainer.RemoveVertex(index)) - { - UpdateVisAreaObject(); - return true; - } - - return false; - } - - void EditorVisAreaComponent::SetVertices(const AZStd::vector& vertices) - { - m_config.m_vertexContainer.SetVertices(vertices); - UpdateVisAreaObject(); - } - - void EditorVisAreaComponent::ClearVertices() - { - m_config.m_vertexContainer.Clear(); - UpdateVisAreaObject(); - } - - size_t EditorVisAreaComponent::Size() const - { - return m_config.m_vertexContainer.Size(); - } - - bool EditorVisAreaComponent::Empty() const - { - return m_config.m_vertexContainer.Empty(); - } - - void EditorVisAreaComponent::DisplayEntityViewport( - [[maybe_unused]] const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) - { - /* - The VisArea and Portal share a common strangeness with how they are displayed. - The Legacy visualization is actually incorrect! It's important to know that - the vis volumes essentially act as a points on an XY plane with a known Z - position and a height. The volumes that actually affect rendition are planar - quads with a height. The height is calculated by the largest height value on - a local point + the given height value on the component. - - Also note that this visualization does not display the floors or ceilings of the vis area - volumes. There is currently no way with the display context to easily draw a filled polygon. - We could try to draw some triangles but it would take up a great deal of rendering - time and could potentially slow down the editor more than we want if there are a lot - of volumes. - */ - - const AZStd::vector& vertices = m_config.m_vertexContainer.GetVertices(); - const size_t vertexCount = vertices.size(); - - //We do not want to push a transform with scale or rotation as the - //vis area is always snapped to the XY plane with a height. - //Scale will be applied during flattening - AZ::Transform translation = AZ::Transform::CreateIdentity(); - translation.SetTranslation(m_currentWorldTransform.GetTranslation()); - - debugDisplay.PushMatrix(translation); - debugDisplay.SetColor(s_visAreaColor.GetAsVector4()); - - AZStd::vector transformedPoints; - transformedPoints.resize(vertexCount); - - //Min and max Z value (in local space) - float minZ = FLT_MAX; - float maxZ = FLT_MIN; - - //Apply rotation and scale before removing translation. - //We want translation to apply with the matrix to make things easier - //but we need to calculate a difference in Z after rotation and scaling. - //During the next loop we'll flatten all these points down to a common XY plane - for (size_t i = 0; i < vertexCount; ++i) - { - AZ::Vector3 transformedPoint = m_currentWorldTransform.TransformPoint(vertices[i]); - - //Back into local space - transformedPoints[i] = transformedPoint - m_currentWorldTransform.GetTranslation(); - - const float transformedZ = transformedPoints[i].GetZ(); - - minZ = AZ::GetMin(transformedZ, minZ); - maxZ = AZ::GetMax(transformedZ, maxZ); - } - - //The height of the vis area + the max local height - const float actualHeight = m_config.m_height + maxZ; - - //Draw walls for every line segment - size_t transformedPointCount = transformedPoints.size(); - for (size_t i = 0; i < transformedPointCount; ++i) - { - AZ::Vector3 lowerLeft = AZ::Vector3(); - AZ::Vector3 lowerRight = AZ::Vector3(); - AZ::Vector3 upperRight = AZ::Vector3(); - AZ::Vector3 upperLeft = AZ::Vector3(); - - lowerLeft = transformedPoints[i]; - lowerRight = transformedPoints[(i + 1) % transformedPointCount]; - //The mod with transformedPointCount ensures that for the last vert it will connect back with vert 0 - //If vert count is 10, the last vert will be i = 9 and we want that to create a surface with vert 0 - - //Make all lower points planar - lowerLeft.SetZ(minZ); - lowerRight.SetZ(minZ); - - upperRight = AZ::Vector3(lowerRight.GetX(), lowerRight.GetY(), actualHeight); - upperLeft = AZ::Vector3(lowerLeft.GetX(), lowerLeft.GetY(), actualHeight); - - if (m_config.m_displayFilled) - { - debugDisplay.SetAlpha(0.3f); - //Draw filled quad with two winding orders to make it double sided - debugDisplay.DrawQuad(lowerLeft, lowerRight, upperRight, upperLeft); - debugDisplay.DrawQuad(lowerLeft, upperLeft, upperRight, lowerRight); - } - - debugDisplay.SetAlpha(1.0f); - debugDisplay.DrawLine(lowerLeft, lowerRight); - debugDisplay.DrawLine(lowerRight, upperRight); - debugDisplay.DrawLine(upperRight, upperLeft); - debugDisplay.DrawLine(upperLeft, lowerLeft); - } - - if (m_componentModeDelegate.AddedToComponentMode()) - { - AzToolsFramework::VertexContainerDisplay::DisplayVertexContainerIndices( - debugDisplay, AzToolsFramework::VariableVerticesVertexContainer(m_config.m_vertexContainer), - GetWorldTM(), AZ::Vector3::CreateOne(), IsSelected()); - } - - debugDisplay.PopMatrix(); - } - - void EditorVisAreaComponent::BuildGameEntity(AZ::Entity* gameEntity) - { - gameEntity->CreateComponent(m_config); - } - - AZ::Aabb EditorVisAreaComponent::GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& /*viewportInfo*/) - { - return GetWorldBounds(); - } - - bool EditorVisAreaComponent::EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) - { - AZ::Aabb bbox = GetEditorSelectionBoundsViewport(viewportInfo); - float end; - float t; - - const bool intersection = AZ::Intersect::IntersectRayAABB2( - src, dir.GetReciprocal(), - bbox, t, end) > 0; - - if (intersection) - { - distance = t; - } - - return intersection; - } - - AZ::Aabb EditorVisAreaComponent::GetWorldBounds() - { - return GetLocalBounds().GetTransformedAabb(GetWorldTM()); - } - - AZ::Aabb EditorVisAreaComponent::GetLocalBounds() - { - AZ::Aabb bbox = AZ::Aabb::CreateNull(); - for (const auto& vertex : m_config.m_vertexContainer.GetVertices()) - { - bbox.AddPoint(vertex); - } - bbox.AddPoint(bbox.GetMax() + AZ::Vector3::CreateAxisZ(m_config.m_height)); - return bbox; - } -} //namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorVisAreaComponent.h b/Gems/Visibility/Code/Source/EditorVisAreaComponent.h deleted file mode 100644 index 45c87e13cc..0000000000 --- a/Gems/Visibility/Code/Source/EditorVisAreaComponent.h +++ /dev/null @@ -1,144 +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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "EditorVisAreaComponentBus.h" -#include "VisAreaComponent.h" - -namespace Visibility -{ - class EditorVisAreaComponent; - - class EditorVisAreaConfiguration - : public VisAreaConfiguration - { - public: - AZ_TYPE_INFO_LEGACY(EditorVisAreaConfiguration, "{C329E65C-1F34-5C80-9A7A-4B568105256B}", VisAreaConfiguration); - AZ_CLASS_ALLOCATOR(EditorVisAreaConfiguration, AZ::SystemAllocator,0); - - static void Reflect(AZ::ReflectContext* context); - - void ChangeHeight() override; - void ChangeDisplayFilled() override; - void ChangeAffectedBySun() override; - void ChangeViewDistRatio() override; - void ChangeOceanIsVisible() override; - void ChangeVertexContainer() override; - - void SetEntityId(AZ::EntityId entityId); - - private: - AZ::EntityId m_entityId; - }; - - class EditorVisAreaComponent - : public AzToolsFramework::Components::EditorComponentBase - , private EditorVisAreaComponentRequestBus::Handler - , private AZ::FixedVerticesRequestBus::Handler - , private AZ::VariableVerticesRequestBus::Handler - , private AzFramework::EntityDebugDisplayEventBus::Handler - , private AzToolsFramework::EditorEntityInfoNotificationBus::Handler - , private AzToolsFramework::EditorComponentSelectionRequestsBus::Handler - , private AZ::TransformNotificationBus::Handler - , public AzFramework::BoundsRequestBus::Handler - { - friend class EditorVisAreaConfiguration; //So that the config can set m_vertices when the vertex container changes - - using Base = AzToolsFramework::Components::EditorComponentBase; - - public: - AZ_COMPONENT(EditorVisAreaComponent, "{F4EC32D8-D4DD-54F7-97A8-D195497D5F2C}", AzToolsFramework::Components::EditorComponentBase); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - static void Reflect(AZ::ReflectContext* context); - - EditorVisAreaComponent() = default; - EditorVisAreaComponent(const EditorVisAreaComponent&) = delete; - EditorVisAreaComponent& operator=(const EditorVisAreaComponent&) = delete; - virtual ~EditorVisAreaComponent(); - - // AZ::Component overrides ... - void Activate() override; - void Deactivate() override; - void BuildGameEntity(AZ::Entity* gameEntity) override; - - // TransformNotificationBus overrides ... - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // EditorComponentSelectionRequestsBus overrides ... - AZ::Aabb GetEditorSelectionBoundsViewport( - const AzFramework::ViewportInfo& viewportInfo) override; - bool EditorSelectionIntersectRayViewport( - const AzFramework::ViewportInfo& viewportInfo, const AZ::Vector3& src, - const AZ::Vector3& dir, float& distance) override; - bool SupportsEditorRayIntersect() override { return true; } - - // VisAreaComponentRequestBus overrides ... - void SetHeight(float height) override; - float GetHeight() override; - void SetDisplayFilled(bool filled) override; - bool GetDisplayFilled() override; - void SetAffectedBySun(bool affectedBySun) override; - bool GetAffectedBySun() override; - void SetViewDistRatio(float viewDistRatio) override; - float GetViewDistRatio() override; - void SetOceanIsVisible(bool oceanVisible) override; - bool GetOceanIsVisible() override; - bool GetVertex(size_t index, AZ::Vector3& vertex) const override; - void AddVertex(const AZ::Vector3& vertex) override; - bool UpdateVertex(size_t index, const AZ::Vector3& vertex) override; - bool InsertVertex(size_t index, const AZ::Vector3& vertex) override; - bool RemoveVertex(size_t index) override; - void SetVertices(const AZStd::vector& vertices) override; - void ClearVertices() override; - size_t Size() const override; - bool Empty() const override; - void UpdateVisAreaObject() override; - - // AzFramework::EntityDebugDisplayEventBus overrides ... - void DisplayEntityViewport( - const AzFramework::ViewportInfo& viewportInfo, - AzFramework::DebugDisplayRequests& debugDisplay) override; - - // BoundsRequestBus overrides ... - AZ::Aabb GetWorldBounds() override; - AZ::Aabb GetLocalBounds() override; - - private: - // Reflected members - EditorVisAreaConfiguration m_config; - - using ComponentModeDelegate = AzToolsFramework::ComponentModeFramework::ComponentModeDelegate; - ComponentModeDelegate m_componentModeDelegate; ///< Responsible for detecting ComponentMode activation - ///< and creating a concrete ComponentMode. - - // Unreflected members - AZ::Transform m_currentWorldTransform; - IVisArea* m_area = nullptr; - - static AZ::Color s_visAreaColor; ///< The orange color that all vis-areas draw with. - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.cpp b/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.cpp deleted file mode 100644 index d479e51345..0000000000 --- a/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.cpp +++ /dev/null @@ -1,120 +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 "Visibility_precompiled.h" -#include "EditorVisAreaComponentMode.h" - -#include -#include - -namespace Visibility -{ - AZ_CLASS_ALLOCATOR_IMPL(EditorVisAreaComponentMode, AZ::SystemAllocator, 0) - - EditorVisAreaComponentMode::EditorVisAreaComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType) - : EditorBaseComponentMode(entityComponentIdPair, componentType) - { - CreateManipulators(); - - AZ::TransformNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - EditorVisAreaComponentNotificationBus::Handler::BusConnect(entityComponentIdPair.GetEntityId()); - } - - EditorVisAreaComponentMode::~EditorVisAreaComponentMode() - { - EditorVisAreaComponentNotificationBus::Handler::BusDisconnect(); - AZ::TransformNotificationBus::Handler::BusDisconnect(); - - m_vertexSelection.Destroy(); - } - - void EditorVisAreaComponentMode::CreateManipulators() - { - using namespace AzToolsFramework; - - m_vertexSelection.Create( - GetEntityComponentIdPair(), g_mainManipulatorManagerId, - AZStd::make_unique>(GetEntityComponentIdPair(), g_mainManipulatorManagerId), - TranslationManipulators::Dimensions::Three, - ConfigureTranslationManipulatorAppearance3d); - - m_vertexSelection.SetVertexPositionsUpdatedCallback([this]() - { - EditorVisAreaComponentRequestBus::Event( - GetEntityId(), &EditorVisAreaComponentRequests::UpdateVisAreaObject); - }); - } - - void EditorVisAreaComponentMode::OnTransformChanged( - const AZ::Transform& /*local*/, const AZ::Transform& world) - { - m_vertexSelection.RefreshSpace(world); - } - - void EditorVisAreaComponentMode::OnVertexAdded(size_t index) - { - Refresh(); - - AZ::Vector3 vertex; - bool found = false; - AZ::FixedVerticesRequestBus::EventResult( - found, GetEntityId(), &AZ::FixedVerticesRequestBus::Handler::GetVertex, - index, vertex); - - if (found) - { - m_vertexSelection.CreateTranslationManipulator( - GetEntityComponentIdPair(), AzToolsFramework::g_mainManipulatorManagerId, - vertex, index); - } - } - - void EditorVisAreaComponentMode::OnVertexRemoved(size_t /*index*/) - { - Refresh(); - } - - void EditorVisAreaComponentMode::OnVerticesSet(const AZStd::vector& /*vertices*/) - { - Refresh(); - } - - void EditorVisAreaComponentMode::OnVerticesCleared() - { - Refresh(); - } - - void EditorVisAreaComponentMode::Refresh() - { - // destroy and recreate manipulators when container is modified (vertices are added or removed) - m_vertexSelection.Destroy(); - CreateManipulators(); - } - - AZStd::vector EditorVisAreaComponentMode::PopulateActionsImpl() - { - return m_vertexSelection.ActionOverrides(); - } - - bool EditorVisAreaComponentMode::HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) - { - return m_vertexSelection.HandleMouse(mouseInteraction); - } - - AZStd::string EditorVisAreaComponentMode::GetComponentModeName() const - { - return "Vis Area Edit Mode"; - } - -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.h b/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.h deleted file mode 100644 index e33aed32f0..0000000000 --- a/Gems/Visibility/Code/Source/EditorVisAreaComponentMode.h +++ /dev/null @@ -1,58 +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 -#include - -#include "EditorVisAreaComponentBus.h" - -namespace Visibility -{ - /// The ComponentMode for editing the Vis Area Component. - class EditorVisAreaComponentMode - : public AzToolsFramework::ComponentModeFramework::EditorBaseComponentMode - , private AZ::TransformNotificationBus::Handler - , private EditorVisAreaComponentNotificationBus::Handler - { - public: - AZ_CLASS_ALLOCATOR_DECL - - EditorVisAreaComponentMode( - const AZ::EntityComponentIdPair& entityComponentIdPair, AZ::Uuid componentType); - ~EditorVisAreaComponentMode(); - - private: - // EditorBaseComponentMode - void Refresh() override; - AZStd::vector PopulateActionsImpl() override; - bool HandleMouseInteraction( - const AzToolsFramework::ViewportInteraction::MouseInteractionEvent& mouseInteraction) override; - AZStd::string GetComponentModeName() const override; - - // Manipulator handling - void CreateManipulators(); - - // TransformNotificationBus - void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; - - // EditorVisAreaComponentNotificationBus - void OnVertexAdded(size_t index) override; - void OnVertexRemoved(size_t index) override; - void OnVerticesSet(const AZStd::vector& vertices) override; - void OnVerticesCleared() override; - - AzToolsFramework::EditorVertexSelectionVariable m_vertexSelection; ///< Handles all manipulator interactions with vertices (inserting and translating). - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/OccluderAreaComponent.cpp b/Gems/Visibility/Code/Source/OccluderAreaComponent.cpp deleted file mode 100644 index 947bc3a38b..0000000000 --- a/Gems/Visibility/Code/Source/OccluderAreaComponent.cpp +++ /dev/null @@ -1,115 +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 "Visibility_precompiled.h" -#include "OccluderAreaComponent.h" - -#include -#include -#include - -namespace Visibility -{ - void OccluderAreaComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides) - { - provides.push_back(AZ_CRC("OccluderAreaService")); - } - void OccluderAreaComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires) - { - requires.push_back(AZ_CRC("TransformService")); - } - - void OccluderAreaConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("DisplayFilled", &OccluderAreaConfiguration::m_displayFilled) - ->Field("CullDistRatio", &OccluderAreaConfiguration::m_cullDistRatio) - ->Field("UseInIndoors", &OccluderAreaConfiguration::m_useInIndoors) - ->Field("DoubleSide", &OccluderAreaConfiguration::m_doubleSide) - ->Field("vertices", &OccluderAreaConfiguration::m_vertices) - ; - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("OccluderAreaRequestBus") - ->Event("GetDisplayFilled", &OccluderAreaRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", nullptr) - - ->Event("GetCullDistRatio", &OccluderAreaRequestBus::Events::GetCullDistRatio) - ->VirtualProperty("CullDistRatio", "GetCullDistRatio", nullptr) - - ->Event("GetUseInIndoors", &OccluderAreaRequestBus::Events::GetUseInIndoors) - ->VirtualProperty("UseInIndoors", "GetUseInIndoors", nullptr) - - ->Event("GetDoubleSide", &OccluderAreaRequestBus::Events::GetDoubleSide) - ->VirtualProperty("DoubleSide", "GetDoubleSide", nullptr) - ; - - behaviorContext->Class()->RequestBus("OccluderAreaRequestBus"); - } - } - - void OccluderAreaComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("m_config", &OccluderAreaComponent::m_config) - ; - } - - OccluderAreaConfiguration::Reflect(context); - } - - OccluderAreaComponent::OccluderAreaComponent(const OccluderAreaConfiguration& params) - : m_config(params) - { - } - - void OccluderAreaComponent::Activate() - { - OccluderAreaRequestBus::Handler::BusConnect(GetEntityId()); - AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId()); - } - - void OccluderAreaComponent::Deactivate() - { - AZ::TransformNotificationBus::Handler::BusDisconnect(GetEntityId()); - OccluderAreaRequestBus::Handler::BusDisconnect(GetEntityId()); - } - - bool OccluderAreaComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - float OccluderAreaComponent::GetCullDistRatio() - { - return m_config.m_cullDistRatio; - } - - bool OccluderAreaComponent::GetUseInIndoors() - { - return m_config.m_useInIndoors; - } - - bool OccluderAreaComponent::GetDoubleSide() - { - return m_config.m_doubleSide; - } - -} //namespace Visibility diff --git a/Gems/Visibility/Code/Source/OccluderAreaComponent.h b/Gems/Visibility/Code/Source/OccluderAreaComponent.h deleted file mode 100644 index 80d98af4df..0000000000 --- a/Gems/Visibility/Code/Source/OccluderAreaComponent.h +++ /dev/null @@ -1,79 +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 -#include - -#include "OccluderAreaComponentBus.h" - -namespace Visibility -{ - class OccluderAreaConfiguration - { - public: - AZ_TYPE_INFO(OccluderAreaConfiguration, "{F024EC7E-717F-576C-8C22-09CAFEFEAF29}"); - AZ_CLASS_ALLOCATOR(OccluderAreaConfiguration, AZ::SystemAllocator, 0); - - virtual ~OccluderAreaConfiguration() = default; - - static void Reflect(AZ::ReflectContext* context); - - bool m_displayFilled = true; - float m_cullDistRatio = 100.0f; - bool m_useInIndoors = false; - bool m_doubleSide = true; - - AZStd::array m_vertices = - AZStd::array { { - AZ::Vector3(-1.0f, -1.0f, 0.0f), - AZ::Vector3( 1.0f, -1.0f, 0.0f), - AZ::Vector3( 1.0f, 1.0f, 0.0f), - AZ::Vector3(-1.0f, 1.0f, 0.0f) - } }; - - virtual void OnChange() {} - virtual void OnVerticesChange() {} - }; - - class OccluderAreaComponent - : public AZ::Component - , private OccluderAreaRequestBus::Handler - , public AZ::TransformNotificationBus::Handler - { - public: - AZ_COMPONENT(OccluderAreaComponent, "{B3C90C5F-0F9B-5D4F-ABAE-6D16CB45CB5A}", AZ::Component); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires); - static void Reflect(AZ::ReflectContext* context); - - OccluderAreaComponent() = default; - explicit OccluderAreaComponent(const OccluderAreaConfiguration& params); - - // AZ::Component - void Activate() override; - void Deactivate() override; - - // OccluderAreaRequestBus - bool GetDisplayFilled() override; - float GetCullDistRatio() override; - bool GetUseInIndoors() override; - bool GetDoubleSide() override; - - protected: - // Reflected Data - OccluderAreaConfiguration m_config; - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/PortalComponent.cpp b/Gems/Visibility/Code/Source/PortalComponent.cpp deleted file mode 100644 index 9f1f618607..0000000000 --- a/Gems/Visibility/Code/Source/PortalComponent.cpp +++ /dev/null @@ -1,182 +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 "Visibility_precompiled.h" -#include "PortalComponent.h" - -#include -#include - -namespace Visibility -{ - void PortalComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides) - { - provides.push_back(AZ::Crc32("PortalService")); - } - - void PortalComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires) - { - requires.push_back(AZ::Crc32("TransformService")); - } - - void PortalConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("Height", &PortalConfiguration::m_height) - ->Field("DisplayFilled", &PortalConfiguration::m_displayFilled) - ->Field("AffectedBySun", &PortalConfiguration::m_affectedBySun) - ->Field("ViewDistRatio", &PortalConfiguration::m_viewDistRatio) - ->Field("SkyOnly", &PortalConfiguration::m_skyOnly) - ->Field("OceanIsVisible", &PortalConfiguration::m_oceanIsVisible) - ->Field("UseDeepness", &PortalConfiguration::m_useDeepness) - ->Field("DoubleSide", &PortalConfiguration::m_doubleSide) - ->Field("LightBlending", &PortalConfiguration::m_lightBlending) - ->Field("LightBlendValue", &PortalConfiguration::m_lightBlendValue) - ->Field("vertices", &PortalConfiguration::m_vertices) - ; - } - - if (auto* behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("PortalRequestBus") - ->Event("GetHeight", &PortalRequestBus::Events::GetHeight) - ->VirtualProperty("Height", "GetHeight", nullptr) - - ->Event("GetDisplayFilled", &PortalRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", nullptr) - - ->Event("GetAffectedBySun", &PortalRequestBus::Events::GetAffectedBySun) - ->VirtualProperty("AffectedBySun", "GetAffectedBySun", nullptr) - - ->Event("GetViewDistRatio", &PortalRequestBus::Events::GetViewDistRatio) - ->VirtualProperty("ViewDistRatio", "GetViewDistRatio", nullptr) - - ->Event("GetSkyOnly", &PortalRequestBus::Events::GetSkyOnly) - ->VirtualProperty("SkyOnly", "GetSkyOnly", nullptr) - - ->Event("GetOceanIsVisible", &PortalRequestBus::Events::GetOceanIsVisible) - ->VirtualProperty("OceanIsVisible", "GetOceanIsVisible", nullptr) - - ->Event("GetUseDeepness", &PortalRequestBus::Events::GetUseDeepness) - ->VirtualProperty("UseDeepness", "GetUseDeepness", nullptr) - - ->Event("GetDoubleSide", &PortalRequestBus::Events::GetDoubleSide) - ->VirtualProperty("DoubleSide", "GetDoubleSide", nullptr) - - ->Event("GetLightBlending", &PortalRequestBus::Events::GetLightBlending) - ->VirtualProperty("LightBlending", "GetLightBlending", nullptr) - - ->Event("GetLightBlendValue", &PortalRequestBus::Events::GetLightBlendValue) - ->VirtualProperty("LightBlendValue", "GetLightBlendValue", nullptr) - ; - - behaviorContext->Class()->RequestBus("PortalRequestBus"); - } - } - - bool PortalConfiguration::VersionConverter( - [[maybe_unused]] AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) - { - // conversion from version 1: - // - Remove IgnoreSkyColor - // - Remove IgnoreGI - if (classElement.GetVersion() <= 1) - { - classElement.RemoveElementByName(AZ_CRC("IgnoreSkyColor")); - classElement.RemoveElementByName(AZ_CRC("IgnoreGI")); - } - - return true; - } - - void PortalComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("m_config", &PortalComponent::m_config) - ; - } - - PortalConfiguration::Reflect(context); - } - - PortalComponent::PortalComponent(const PortalConfiguration& params) - : m_config(params) - { - } - - void PortalComponent::Activate() - { - PortalRequestBus::Handler::BusConnect(GetEntityId()); - } - - void PortalComponent::Deactivate() - { - PortalRequestBus::Handler::BusDisconnect(GetEntityId()); - } - - float PortalComponent::GetHeight() - { - return m_config.m_height; - } - - bool PortalComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - bool PortalComponent::GetAffectedBySun() - { - return m_config.m_affectedBySun; - } - - float PortalComponent::GetViewDistRatio() - { - return m_config.m_viewDistRatio; - } - - bool PortalComponent::GetSkyOnly() - { - return m_config.m_skyOnly; - } - - bool PortalComponent::GetOceanIsVisible() - { - return m_config.m_oceanIsVisible; - } - - bool PortalComponent::GetUseDeepness() - { - return m_config.m_useDeepness; - } - - bool PortalComponent::GetDoubleSide() - { - return m_config.m_doubleSide; - } - - bool PortalComponent::GetLightBlending() - { - return m_config.m_lightBlending; - } - - float PortalComponent::GetLightBlendValue() - { - return m_config.m_lightBlendValue; - } - -} //namespace Visibility diff --git a/Gems/Visibility/Code/Source/PortalComponent.h b/Gems/Visibility/Code/Source/PortalComponent.h deleted file mode 100644 index fd6ce4ab77..0000000000 --- a/Gems/Visibility/Code/Source/PortalComponent.h +++ /dev/null @@ -1,92 +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 -#include - -#include "PortalComponentBus.h" - -namespace Visibility -{ - class PortalConfiguration - { - public: - AZ_TYPE_INFO(PortalConfiguration, "{B9BDF017-DF8B-5DBE-8A92-5F62B7AECC1C}"); - AZ_CLASS_ALLOCATOR(PortalConfiguration, AZ::SystemAllocator,0); - - virtual ~PortalConfiguration() = default; - - static void Reflect(AZ::ReflectContext* context); - static bool VersionConverter( - AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); - - float m_height = 1.0f; - bool m_displayFilled = false; - bool m_affectedBySun = false; - float m_viewDistRatio = 100.0f; - bool m_skyOnly = false; - bool m_oceanIsVisible = false; - bool m_useDeepness = true; - bool m_doubleSide = true; - bool m_lightBlending = true; - float m_lightBlendValue = 0.5f; - - AZStd::array m_vertices = - AZStd::array { { - AZ::Vector3(-1.0f, -1.0f, 0.0f), - AZ::Vector3( 1.0f, -1.0f, 0.0f), - AZ::Vector3( 1.0f, 1.0f, 0.0f), - AZ::Vector3(-1.0f, 1.0f, 0.0f) - } }; - - virtual void OnChange() {} - virtual void OnVerticesChange() {} - }; - - class PortalComponent - : public AZ::Component - , private PortalRequestBus::Handler - { - public: - AZ_COMPONENT(PortalComponent, "{89F1DD88-4445-5A9D-9223-6D4D8D44E6AC}", AZ::Component); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires); - static void Reflect(AZ::ReflectContext* context); - - PortalComponent() = default; - explicit PortalComponent(const PortalConfiguration& params); - - // AZ::Component - void Activate() override; - void Deactivate() override; - - // PortalRequestBus - float GetHeight() override; - bool GetDisplayFilled() override; - bool GetAffectedBySun() override; - float GetViewDistRatio() override; - bool GetSkyOnly() override; - bool GetOceanIsVisible() override; - bool GetUseDeepness() override; - bool GetDoubleSide() override; - bool GetLightBlending() override; - float GetLightBlendValue() override; - - protected: - // Reflected Data - PortalConfiguration m_config; - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/VisAreaComponent.cpp b/Gems/Visibility/Code/Source/VisAreaComponent.cpp deleted file mode 100644 index 7db60f1688..0000000000 --- a/Gems/Visibility/Code/Source/VisAreaComponent.cpp +++ /dev/null @@ -1,137 +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 "Visibility_precompiled.h" -#include "VisAreaComponent.h" - -#include -#include - -namespace Visibility -{ - void VisAreaComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides) - { - provides.push_back(AZ::Crc32("VisAreaService")); - } - - void VisAreaComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires) - { - requires.push_back(AZ::Crc32("TransformService")); - } - - void VisAreaConfiguration::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(2, &VersionConverter) - ->Field("m_Height", &VisAreaConfiguration::m_height) - ->Field("m_DisplayFilled", &VisAreaConfiguration::m_displayFilled) - ->Field("m_AffectedBySun", &VisAreaConfiguration::m_affectedBySun) - ->Field("m_ViewDistRatio", &VisAreaConfiguration::m_viewDistRatio) - ->Field("m_OceanIsVisible", &VisAreaConfiguration::m_oceanIsVisible) - ->Field("m_vertexContainer", &VisAreaConfiguration::m_vertexContainer) - ; - } - - if (auto behaviorContext = azrtti_cast(context)) - { - behaviorContext->EBus("VisAreaComponentRequestBus") - ->Event("GetHeight", &VisAreaComponentRequestBus::Events::GetHeight) - ->VirtualProperty("Height", "GetHeight", nullptr) - - ->Event("GetDisplayFilled", &VisAreaComponentRequestBus::Events::GetDisplayFilled) - ->VirtualProperty("DisplayFilled", "GetDisplayFilled", nullptr) - - ->Event("GetAffectedBySun", &VisAreaComponentRequestBus::Events::GetAffectedBySun) - ->VirtualProperty("AffectedBySun", "GetAffectedBySun", nullptr) - - ->Event("GetViewDistRatio", &VisAreaComponentRequestBus::Events::GetViewDistRatio) - ->VirtualProperty("ViewDistRatio", "GetViewDistRatio", nullptr) - - ->Event("GetOceanIsVisible", &VisAreaComponentRequestBus::Events::GetOceanIsVisible) - ->VirtualProperty("OceanIsVisible", "GetOceanIsVisible", nullptr) - ; - - behaviorContext->Class()->RequestBus("VisAreaComponentRequestBus"); - } - } - - bool VisAreaConfiguration::VersionConverter([[maybe_unused]] AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) - { - // conversion from version 1: - // - Remove IgnoreSkyColor - // - Remove IgnoreGI - // - Remove SkyOnly - if (classElement.GetVersion() <= 1) - { - classElement.RemoveElementByName(AZ_CRC("IgnoreSkyColor")); - classElement.RemoveElementByName(AZ_CRC("IgnoreGI")); - classElement.RemoveElementByName(AZ_CRC("SkyOnly")); - } - - return true; - } - - void VisAreaComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1) - ->Field("m_config", &VisAreaComponent::m_config) - ; - } - - VisAreaConfiguration::Reflect(context); - } - - VisAreaComponent::VisAreaComponent(const VisAreaConfiguration& params) - : m_config(params) - { - } - - void VisAreaComponent::Activate() - { - VisAreaComponentRequestBus::Handler::BusConnect(GetEntityId()); - } - - void VisAreaComponent::Deactivate() - { - VisAreaComponentRequestBus::Handler::BusDisconnect(GetEntityId()); - } - - float VisAreaComponent::GetHeight() - { - return m_config.m_height; - } - - bool VisAreaComponent::GetDisplayFilled() - { - return m_config.m_displayFilled; - } - - bool VisAreaComponent::GetAffectedBySun() - { - return m_config.m_affectedBySun; - } - - float VisAreaComponent::GetViewDistRatio() - { - return m_config.m_viewDistRatio; - } - - bool VisAreaComponent::GetOceanIsVisible() - { - return m_config.m_oceanIsVisible; - } -} //namespace Visibility diff --git a/Gems/Visibility/Code/Source/VisAreaComponent.h b/Gems/Visibility/Code/Source/VisAreaComponent.h deleted file mode 100644 index f2efe7167d..0000000000 --- a/Gems/Visibility/Code/Source/VisAreaComponent.h +++ /dev/null @@ -1,79 +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 -#include -#include - -#include "VisAreaComponentBus.h" - -namespace Visibility -{ - class VisAreaConfiguration - { - public: - AZ_TYPE_INFO(VisAreaConfiguration, "{160D9FC2-936F-59BB-827C-DEF89671E4DC}"); - AZ_CLASS_ALLOCATOR(VisAreaConfiguration, AZ::SystemAllocator,0); - - virtual ~VisAreaConfiguration() = default; - - static void Reflect(AZ::ReflectContext* context); - static bool VersionConverter( - AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); - - float m_height = 5.0f; - bool m_displayFilled = false; - bool m_affectedBySun = false; - float m_viewDistRatio = 100.0f; - bool m_oceanIsVisible = false; - AZ::VertexContainer m_vertexContainer; - - virtual void ChangeHeight() {} - virtual void ChangeDisplayFilled() {} - virtual void ChangeAffectedBySun() {} - virtual void ChangeViewDistRatio() {} - virtual void ChangeOceanIsVisible() {} - virtual void ChangeVertexContainer() {} - }; - - class VisAreaComponent - : public AZ::Component - , private VisAreaComponentRequestBus::Handler - { - public: - AZ_COMPONENT(VisAreaComponent, "{ACAB60F8-100E-5EAF-BE2B-D60F79312404}", AZ::Component); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provides); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& requires); - static void Reflect(AZ::ReflectContext* context); - - VisAreaComponent() = default; - explicit VisAreaComponent(const VisAreaConfiguration& params); - - // AZ::Component - void Activate() override; - void Deactivate() override; - - // VisAreaComponentRequestBus - float GetHeight() override; - bool GetDisplayFilled() override; - bool GetAffectedBySun() override; - float GetViewDistRatio() override; - bool GetOceanIsVisible() override; - - private: - VisAreaConfiguration m_config; ///< Reflected configuration. - }; -} // namespace Visibility diff --git a/Gems/Visibility/Code/Source/VisibilityGem.cpp b/Gems/Visibility/Code/Source/VisibilityGem.cpp deleted file mode 100644 index 37d31a56f6..0000000000 --- a/Gems/Visibility/Code/Source/VisibilityGem.cpp +++ /dev/null @@ -1,39 +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 "Visibility_precompiled.h" - -#include "VisibilityGem.h" - -#include "OccluderAreaComponent.h" -#include "PortalComponent.h" -#include "VisAreaComponent.h" - -#ifdef VISIBILITY_EDITOR -#include "EditorOccluderAreaComponent.h" -#include "EditorPortalComponent.h" -#include "EditorVisAreaComponent.h" -#endif //VISIBILITY_EDITOR - -VisibilityGem::VisibilityGem() -{ - m_descriptors.push_back(Visibility::OccluderAreaComponent::CreateDescriptor()); - m_descriptors.push_back(Visibility::PortalComponent::CreateDescriptor()); - m_descriptors.push_back(Visibility::VisAreaComponent::CreateDescriptor()); - -#ifdef VISIBILITY_EDITOR - m_descriptors.push_back(Visibility::EditorOccluderAreaComponent::CreateDescriptor()); - m_descriptors.push_back(Visibility::EditorPortalComponent::CreateDescriptor()); - m_descriptors.push_back(Visibility::EditorVisAreaComponent::CreateDescriptor()); -#endif //VISIBILITY_EDITOR -} - -AZ_DECLARE_MODULE_CLASS(Gem_Visibility, VisibilityGem) diff --git a/Gems/Visibility/Code/Source/VisibilityGem.h b/Gems/Visibility/Code/Source/VisibilityGem.h deleted file mode 100644 index 1abc1b8901..0000000000 --- a/Gems/Visibility/Code/Source/VisibilityGem.h +++ /dev/null @@ -1,27 +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 - - -class VisibilityGem - : public AZ::Module -{ -public: - AZ_RTTI(VisibilityGem, "{5138F2B6-EDFB-490E-AB3E-B82E43263A20}"); - - VisibilityGem(); -}; diff --git a/Gems/Visibility/Code/Source/Visibility_precompiled.cpp b/Gems/Visibility/Code/Source/Visibility_precompiled.cpp deleted file mode 100644 index 6d32d0ea69..0000000000 --- a/Gems/Visibility/Code/Source/Visibility_precompiled.cpp +++ /dev/null @@ -1,12 +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 "Visibility_precompiled.h" diff --git a/Gems/Visibility/Code/Source/Visibility_precompiled.h b/Gems/Visibility/Code/Source/Visibility_precompiled.h deleted file mode 100644 index 2a1bc2e083..0000000000 --- a/Gems/Visibility/Code/Source/Visibility_precompiled.h +++ /dev/null @@ -1,19 +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 -#include -#include -#include diff --git a/Gems/Visibility/Code/Tests/VisibilityTest.cpp b/Gems/Visibility/Code/Tests/VisibilityTest.cpp deleted file mode 100644 index 406cef86a4..0000000000 --- a/Gems/Visibility/Code/Tests/VisibilityTest.cpp +++ /dev/null @@ -1,184 +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 "Visibility_precompiled.h" - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -class VisibilityTest - : public ::testing::Test -{ -protected: - - void SetUp() override - { - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_memoryBlocksByteSize = 10 * 1024 * 1024; - appDesc.m_recordingMode = AZ::Debug::AllocationRecords::RECORD_FULL; - - AZ::ComponentApplication::StartupParameters appStartup; - appStartup.m_createStaticModulesCallback = - [](AZStd::vector& modules) - { - modules.emplace_back(new VisibilityGem); - }; - - m_systemEntity = m_application.Create(appDesc, appStartup); - m_systemEntity->Init(); - m_systemEntity->Activate(); - - m_application.RegisterComponentDescriptor(AzFramework::TransformComponent::CreateDescriptor()); - m_application.RegisterComponentDescriptor(Visibility::OccluderAreaComponent::CreateDescriptor()); - m_application.RegisterComponentDescriptor(Visibility::PortalComponent::CreateDescriptor()); - m_application.RegisterComponentDescriptor(Visibility::VisAreaComponent::CreateDescriptor()); - } - - void TearDown() override - { - m_application.Destroy(); - } - - AZ::ComponentApplication m_application; - AZ::Entity* m_systemEntity; -}; - -#include -#include -#include - -TEST_F(VisibilityTest, Occluder_TestIntersect) -{ - AZ::Entity* testEntity = aznew AZ::Entity(); - ASSERT_TRUE(testEntity != nullptr); - - testEntity->CreateComponent(); - testEntity->CreateComponent(); - - Visibility::EditorOccluderAreaComponent* oaComp = testEntity->FindComponent(); - ASSERT_TRUE(oaComp != nullptr); - testEntity->Init(); - testEntity->Activate(); - - // Test CCW tri intersection test - const AZ::Vector3 src(0, 0, 10); - const AZ::Vector3 dir(0, 0, -1); - float distance; - - // Visibility Components do not make use of the ViewportInfo to determine - // camera position etc. - AzFramework::ViewportInfo viewportInfo{}; - - bool didHit = oaComp->EditorSelectionIntersectRayViewport(viewportInfo, src, dir, distance); - ASSERT_TRUE(didHit); - ASSERT_NEAR(distance, 10, 0.1f); // Occluder is a flat plane - - // Test CW tri intersection test - const AZ::Vector3 srcNeg(0, 0, -10); - const AZ::Vector3 dirNeg(0, 0, 1); - - didHit = oaComp->EditorSelectionIntersectRayViewport(viewportInfo, srcNeg, dirNeg, distance); - ASSERT_TRUE(didHit); - ASSERT_NEAR(distance, 10, 0.1f); // Occluder is a flat plane - - // Test intersect failure - const AZ::Vector3 badDir(100, 100, -1); - didHit = oaComp->EditorSelectionIntersectRayViewport(viewportInfo, src, badDir, distance); - ASSERT_FALSE(didHit); -} - -TEST_F(VisibilityTest, Portal_TestIntersect) -{ - AZ::Entity* testEntity = aznew AZ::Entity(); - ASSERT_TRUE(testEntity != nullptr); - - testEntity->CreateComponent(); - testEntity->CreateComponent(); - - Visibility::EditorPortalComponent* pComp = testEntity->FindComponent(); - ASSERT_TRUE(pComp != nullptr); - testEntity->Init(); - testEntity->Activate(); - - const AZ::Vector3 src(0, 0, 10); - const AZ::Vector3 dir(0, 0, -1); - float distance; - - // Visibility Components do not make use of the ViewportInfo to determine - // camera position etc. - AzFramework::ViewportInfo viewportInfo{}; - - // Test intersect - bool didHit = pComp->EditorSelectionIntersectRayViewport(viewportInfo, src, dir, distance); - ASSERT_TRUE(didHit); - ASSERT_NEAR(distance, 9, 0.1f); // Portal has a default height of 1 - - // Test casting a ray from inside the geom - const AZ::Vector3 internalSrc(0, 0, 0.5f); - didHit = pComp->EditorSelectionIntersectRayViewport(viewportInfo, internalSrc, dir, distance); - ASSERT_FALSE(didHit); - - // Test intersect failure - const AZ::Vector3 badDir(100, 100, -1); - didHit = pComp->EditorSelectionIntersectRayViewport(viewportInfo, src, badDir, distance); - ASSERT_FALSE(didHit); -} - -TEST_F(VisibilityTest, VisArea_TestIntersect) -{ - AZ::Entity* testEntity = aznew AZ::Entity(); - ASSERT_TRUE(testEntity != nullptr); - - testEntity->CreateComponent(); - testEntity->CreateComponent(); - testEntity->Init(); - testEntity->Activate(); - - Visibility::EditorVisAreaComponent* vaComp = testEntity->FindComponent(); - ASSERT_TRUE(vaComp != nullptr); - - const AZ::Vector3 src(0, 0, 10); - const AZ::Vector3 dir(0, 0, -1); - float distance; - - // Visibility Components do not make use of the ViewportInfo to determine - // camera position etc. - AzFramework::ViewportInfo viewportInfo{}; - - bool didHit = vaComp->EditorSelectionIntersectRayViewport(viewportInfo, src, dir, distance); - ASSERT_TRUE(didHit); - ASSERT_NEAR(distance, 5, 0.1f); // VisArea has a default height of 5 - - const AZ::Vector3 badDir(100, 100, -1); - didHit = vaComp->EditorSelectionIntersectRayViewport(viewportInfo, src, badDir, distance); - ASSERT_FALSE(didHit); -} - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/Gems/Visibility/Code/visibility_editor_files.cmake b/Gems/Visibility/Code/visibility_editor_files.cmake deleted file mode 100644 index 9d17b92e27..0000000000 --- a/Gems/Visibility/Code/visibility_editor_files.cmake +++ /dev/null @@ -1,22 +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. -# - -set(FILES - Include/EditorOccluderAreaComponentBus.h - Include/EditorPortalComponentBus.h - Include/EditorVisAreaComponentBus.h - Source/EditorOccluderAreaComponentMode.h - Source/EditorOccluderAreaComponentMode.cpp - Source/EditorPortalComponentMode.h - Source/EditorPortalComponentMode.cpp - Source/EditorVisAreaComponentMode.h - Source/EditorVisAreaComponentMode.cpp -) diff --git a/Gems/Visibility/Code/visibility_editor_shared_files.cmake b/Gems/Visibility/Code/visibility_editor_shared_files.cmake deleted file mode 100644 index 1714fc1402..0000000000 --- a/Gems/Visibility/Code/visibility_editor_shared_files.cmake +++ /dev/null @@ -1,21 +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. -# - -set(FILES - Source/VisibilityGem.h - Source/VisibilityGem.cpp - Source/EditorOccluderAreaComponent.h - Source/EditorOccluderAreaComponent.cpp - Source/EditorPortalComponent.h - Source/EditorPortalComponent.cpp - Source/EditorVisAreaComponent.h - Source/EditorVisAreaComponent.cpp -) diff --git a/Gems/Visibility/Code/visibility_editor_tests_files.cmake b/Gems/Visibility/Code/visibility_editor_tests_files.cmake deleted file mode 100644 index 52867e64af..0000000000 --- a/Gems/Visibility/Code/visibility_editor_tests_files.cmake +++ /dev/null @@ -1,22 +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. -# - -set(FILES - Tests/VisibilityTest.cpp - Source/VisibilityGem.h - Source/VisibilityGem.cpp - Source/EditorOccluderAreaComponent.h - Source/EditorOccluderAreaComponent.cpp - Source/EditorPortalComponent.h - Source/EditorPortalComponent.cpp - Source/EditorVisAreaComponent.h - Source/EditorVisAreaComponent.cpp -) diff --git a/Gems/Visibility/Code/visibility_files.cmake b/Gems/Visibility/Code/visibility_files.cmake deleted file mode 100644 index e58ac4fbba..0000000000 --- a/Gems/Visibility/Code/visibility_files.cmake +++ /dev/null @@ -1,24 +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. -# - -set(FILES - Source/Visibility_precompiled.cpp - Source/Visibility_precompiled.h - Include/OccluderAreaComponentBus.h - Include/PortalComponentBus.h - Include/VisAreaComponentBus.h - Source/OccluderAreaComponent.h - Source/OccluderAreaComponent.cpp - Source/PortalComponent.h - Source/PortalComponent.cpp - Source/VisAreaComponent.h - Source/VisAreaComponent.cpp -) diff --git a/Gems/Visibility/Code/visibility_shared_files.cmake b/Gems/Visibility/Code/visibility_shared_files.cmake deleted file mode 100644 index a37350ade6..0000000000 --- a/Gems/Visibility/Code/visibility_shared_files.cmake +++ /dev/null @@ -1,15 +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. -# - -set(FILES - Source/VisibilityGem.h - Source/VisibilityGem.cpp -) diff --git a/Gems/Visibility/gem.json b/Gems/Visibility/gem.json deleted file mode 100644 index 3e8eca471b..0000000000 --- a/Gems/Visibility/gem.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "gem_name": "Visibility", - "GemFormatVersion": 3, - "Uuid": "3b4ab3f54c2749328934c5b864355a61", - "Name": "Visibility", - "DisplayName": "Visibility", - "Version": "0.1.0", - "LinkType": "Dynamic", - "Summary": "Provides components for defining visible regions of a scene", - "Tags": ["Untagged"], - "IconPath": "preview.png", - "EditorModule": true -} diff --git a/Gems/Visibility/preview.png b/Gems/Visibility/preview.png deleted file mode 100644 index f60ab5eebd..0000000000 --- a/Gems/Visibility/preview.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f1a3e838ba075704ee974a1289487d4007e7b7385eb855b8b2a09534b6cecd1 -size 1949 diff --git a/Registry/application_options.setreg b/Registry/application_options.setreg new file mode 100644 index 0000000000..06ccdc9b41 --- /dev/null +++ b/Registry/application_options.setreg @@ -0,0 +1,17 @@ +{ + "O3DE" : { + "AzCore": { + "Application": { + "ValidCommandOptions": [ + "project-path", + "engine-path", + "project-cache-path", + "regset", + "regremove", + "regdump", + "regdumpall" + ] + } + } + } +} diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 0686b27fe7..edbcdc473b 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -357,7 +357,7 @@ endfunction() function(ly_setup_others) # List of directories we want to install relative to engine root - set(DIRECTORIES_TO_INSTALL Tools/LyTestTools Tools/RemoteConsole scripts) + set(DIRECTORIES_TO_INSTALL Tools/LyTestTools Tools/RemoteConsole) foreach(dir ${DIRECTORIES_TO_INSTALL}) get_filename_component(install_path ${dir} DIRECTORY) @@ -372,6 +372,24 @@ function(ly_setup_others) endforeach() + # Scripts + file(GLOB o3de_scripts "${CMAKE_SOURCE_DIR}/scripts/o3de.*") + install(FILES + ${o3de_scripts} + DESTINATION ./scripts + COMPONENT ${LY_DEFAULT_INSTALL_COMPONENT} + ) + + install(DIRECTORY + ${CMAKE_SOURCE_DIR}/scripts/bundler + ${CMAKE_SOURCE_DIR}/scripts/project_manager + DESTINATION ./scripts + COMPONENT ${LY_DEFAULT_INSTALL_COMPONENT} + PATTERN "__pycache__" EXCLUDE + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN "tests" EXCLUDE + ) + install(DIRECTORY "${CMAKE_SOURCE_DIR}/python" DESTINATION . COMPONENT ${LY_DEFAULT_INSTALL_COMPONENT}