Merged main in

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

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