Merge remote-tracking branch 'upstream/stabilization/2106' into santorac/stabilization/2106/RemoveShader2-ATOM-15837

This commit is contained in:
Chris Santora
2021-06-25 10:31:24 -07:00
51 changed files with 581 additions and 278 deletions
@@ -18,11 +18,6 @@ public:
// Public functions
//! Initialize the UI system. This should be called when all other systems that the UI
//! system depends upon are initialized. Once the engine is fully modularized this
//! function will be unnecessary.
virtual void InitializeSystem() {}
//! Register a component type with the UI system.
//! The order in which component types are registered is the order that they show up in
//! the add component and in the properties pane.
-1
View File
@@ -431,7 +431,6 @@ private:
bool InitFileSystem();
bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams);
bool InitAudioSystem(const SSystemInitParams& initParams);
bool InitShine(const SSystemInitParams& initParams);
//@}
-24
View File
@@ -852,16 +852,6 @@ bool CSystem::InitVTuneProfiler()
return true;
}
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitShine([[maybe_unused]] const SSystemInitParams& initParams)
{
LOADING_TIME_PROFILE_SECTION(GetISystem());
EBUS_EVENT(UiSystemBus, InitializeSystem);
return true;
}
//////////////////////////////////////////////////////////////////////////
void CSystem::InitLocalization()
{
@@ -1550,20 +1540,6 @@ AZ_POP_DISABLE_WARNING
}
m_Time.ResetTimer();
//////////////////////////////////////////////////////////////////////////
// UI. Should be after input and hardware mouse
//////////////////////////////////////////////////////////////////////////
if (!m_bDedicatedServer)
{
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "UI system initialization");
INDENT_LOG_DURING_SCOPE();
if (!InitShine(startupParams))
{
return false;
}
}
InlineInitializationProcessing("CSystem::Init InitShine");
// CONSOLE
//////////////////////////////////////////////////////////////////////////
if (!InitConsole())
@@ -483,6 +483,9 @@ namespace AZ
// tell the caller of this function to write the type id and provide a default object, if requested, for
// the specific polymorphic instance the pointer is pointing to.
const AZ::Uuid& actualClassId = rtti.GetActualUuid(object);
// Note: If it is crashing here, it might be that you're serializing a pointer and forgot to initialize it with nullptr.
// Check the elementClassData to identify the causing element.
const AZ::Uuid& actualDefaultClassId = rtti.GetActualUuid(defaultObject);
if (actualClassId != rtti.GetTypeId())
@@ -414,7 +414,6 @@ namespace AzToolsFramework
}
m_templateFilePathToIdMap.emplace(AZStd::make_pair(filePath, newTemplateId));
newTemplate.MarkAsDirty(true);
return newTemplateId;
}
@@ -130,10 +130,7 @@ namespace AzToolsFramework
if (!instanceOptionalReference.has_value())
{
AZ_Warning(
"Undo", false,
"PrefabUndoCache was told to update the cache for entity of id %p (%s), but that entity does not have an owning instance.",
entityId, entity->GetName().c_str());
// This is not an error, we just don't handle this entity.
return;
}
-4
View File
@@ -1350,10 +1350,6 @@ void MainWindow::RegisterStdViewClasses()
AzAssetBrowserWindow::RegisterViewClass();
AssetEditorWindow::RegisterViewClass();
//These view dialogs aren't used anymore so they became disabled.
//CLightmapCompilerDialog::RegisterViewClass();
//CLightmapCompilerDialog::RegisterViewClass();
// Notify that views can now be registered
AzToolsFramework::EditorEvents::Bus::Broadcast(
&AzToolsFramework::EditorEvents::Bus::Events::NotifyRegisterViews);
@@ -175,6 +175,14 @@ namespace O3DE::ProjectManager
ShowOverlay();
}
void CartButton::hideEvent(QHideEvent*)
{
if (m_cartOverlay)
{
m_cartOverlay->hide();
}
}
void CartButton::ShowOverlay()
{
const QVector<QModelIndex> toBeAdded = m_gemModel->GatherGemsToBeAdded();
@@ -16,6 +16,7 @@
#include <QLabel>
#include <QDialog>
#include <QMoveEvent>
#include <QHideEvent>
#include <QVBoxLayout>
#endif
@@ -59,6 +60,7 @@ namespace O3DE::ProjectManager
private:
void mousePressEvent(QMouseEvent* event) override;
void hideEvent(QHideEvent*) override;
GemModel* m_gemModel = nullptr;
QHBoxLayout* m_layout = nullptr;
@@ -24,8 +24,8 @@
namespace O3DE::ProjectManager
{
// 10 Minutes
constexpr int MaxBuildTimeMSecs = 600000;
// QProcess::waitForFinished uses -1 to indicate that the process should not timeout
constexpr int MaxBuildTimeMSecs = -1;
ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo)
: QObject()
@@ -13,7 +13,7 @@ namespace O3DE::ProjectManager
inline constexpr static int ProjectPreviewImageWidth = 210;
inline constexpr static int ProjectPreviewImageHeight = 280;
static const QString ProjectBuildPathPostfix = "Windows_VS2019";
static const QString ProjectBuildPathPostfix = "build/windows_vs2019";
static const QString ProjectBuildErrorLogPathPostfix = "CMakeFiles/CMakeProjectBuildError.log";
static const QString ProjectPreviewImagePath = "preview.png";
} // namespace O3DE::ProjectManager
@@ -14,6 +14,7 @@
#include <QFileInfo>
#include <QProcess>
#include <QProcessEnvironment>
#include <QGuiApplication>
namespace O3DE::ProjectManager
{
@@ -118,9 +119,10 @@ namespace O3DE::ProjectManager
return false;
}
// TODO: Block UX and Notify User they need to wait
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
copyResult = CopyProject(origPath, newPath);
QGuiApplication::restoreOverrideCursor();
}
return copyResult;
@@ -41,6 +41,7 @@
#include <QTimer>
#include <QQueue>
#include <QDir>
#include <QGuiApplication>
//#define DISPLAY_PROJECT_DEV_DATA true
@@ -403,9 +404,11 @@ namespace O3DE::ProjectManager
if (warningResult == QMessageBox::Yes)
{
QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
// Remove project from O3DE and delete from disk
HandleRemoveProject(projectPath);
ProjectUtils::DeleteProjectFiles(projectPath);
QGuiApplication::restoreOverrideCursor();
}
}
}
@@ -58,7 +58,7 @@ namespace ImageProcessingAtom
void ImageThumbnail::LoadThread()
{
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent(
AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Event(
AZ::RPI::StreamingImageAsset::RTTI_Type(), &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail,
m_key,
ImageThumbnailSize);
@@ -714,6 +714,19 @@
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"id": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
"description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)",
"type": "float",
"min": 0.0,
"max": 1.0,
"defaultValue": 0.0,
"connection": {
"type": "ShaderInput",
"id": "m_opacityAffectsSpecularFactor"
}
}
],
"uv": [
@@ -50,6 +50,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
float m_anisotropicFactor; // Base layer anisotropic strength of deviation: negative = Bi-Normal direction, positive = Tangent direction
float m_opacityFactor;
float m_opacityAffectsSpecularFactor;
Texture2D m_opacityMap;
uint m_opacityMapUvIndex;
@@ -326,7 +326,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
{
alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor);
}
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
@@ -344,8 +345,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular
// to be added on top of the diffuse, but then the diffuse must be pre-multiplied.
// It's done this way because surface transparency doesn't really change specular response (eg, glass).
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
@@ -362,7 +368,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
@@ -410,4 +421,3 @@ ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace :
return OUT;
}
@@ -655,6 +655,19 @@
"displayName": "Double-sided",
"description": "Whether to render back-faces or just front-faces.",
"type": "Bool"
},
{
"id": "alphaAffectsSpecular",
"displayName": "Alpha affects specular",
"description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)",
"type": "float",
"min": 0.0,
"max": 1.0,
"defaultValue": 0.0,
"connection": {
"type": "ShaderInput",
"id": "m_opacityAffectsSpecularFactor"
}
}
],
"uv": [
@@ -45,6 +45,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial
float4 m_pad2; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed.
float m_opacityFactor;
float m_opacityAffectsSpecularFactor;
Texture2D m_opacityMap;
uint m_opacityMapUvIndex;
@@ -254,7 +254,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent)
{
alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles.
alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor);
}
PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha);
@@ -269,8 +270,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular
// to be added on top of the diffuse, but then the diffuse must be pre-multiplied.
// It's done this way because surface transparency doesn't really change specular response (eg, glass).
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
}
else if (o_opacity_mode == OpacityMode::TintedTransparent)
{
@@ -287,7 +293,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float
// m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0.
lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse
lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular
// Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution.
float3 specular = lightingOutput.m_specularColor.rgb;
specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor);
lightingOutput.m_diffuseColor.rgb += specular;
lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w);
}
else
@@ -0,0 +1,24 @@
{
"description": "",
"materialType": "Materials/Types/StandardPBR.materialtype",
"parentMaterial": "",
"propertyLayoutVersion": 3,
"properties": {
"baseColor": {
"color": [
0.5906767249107361,
1.0,
0.11703670024871826,
1.0
],
"textureMap": "Textures/Default/default_basecolor.tif"
},
"opacity": {
"alphaSource": "Split",
"factor": 0.75,
"mode": "Blended",
"textureMap": "TestData/Textures/checker8x8_gray_512.png",
"alphaAffectsSpecular": 1.0
}
}
}
@@ -24,48 +24,6 @@
namespace CommandSystem
{
AZStd::vector<MCore::Command*> MetaData::GenerateMotionMetaData(EMotionFX::Motion* motion)
{
AZStd::vector<MCore::Command*> commands;
if (!motion)
{
AZ_Error("EMotionFX", false, "Cannot generate meta data for motion. Motion invalid.");
return commands;
}
// Save event tracks including motion events.
CommandAdjustMotion* adjustMotionCommand = aznew CommandAdjustMotion();
adjustMotionCommand->SetMotionExtractionFlags(motion->GetMotionExtractionFlags());
commands.emplace_back(adjustMotionCommand);
const size_t eventTrackCount = motion->GetEventTable()->GetNumTracks();
for (size_t trackIndex = 0; trackIndex < eventTrackCount; ++trackIndex)
{
const EMotionFX::MotionEventTrack* track = motion->GetEventTable()->GetTrack(trackIndex);
CommandCreateMotionEventTrack* createMotionEventTrackCommand = aznew CommandCreateMotionEventTrack();
createMotionEventTrackCommand->SetEventTrackName(track->GetName());
commands.emplace_back(createMotionEventTrackCommand);
const size_t eventCount = track->GetNumEvents();
for (size_t eventIndex = 0; eventIndex < eventCount; ++eventIndex)
{
const EMotionFX::MotionEvent& event = track->GetEvent(eventIndex);
CommandCreateMotionEvent* createMotionEventCommand = aznew CommandCreateMotionEvent();
commands.emplace_back(createMotionEventCommand);
createMotionEventCommand->SetEventTrackName(track->GetName());
createMotionEventCommand->SetStartTime(event.GetStartTime());
createMotionEventCommand->SetEndTime(event.GetEndTime());
createMotionEventCommand->SetEventDatas(event.GetEventDatas());
}
}
return commands;
}
bool MetaData::ApplyMetaDataOnMotion(EMotionFX::Motion* motion, const AZStd::vector<MCore::Command*>& metaDataCommands)
{
for (MCore::Command* command : metaDataCommands)
@@ -30,13 +30,6 @@ namespace CommandSystem
class COMMANDSYSTEM_API MetaData
{
public:
/**
* Constructs a list of commands representing the changes the user did on the source asset and returns it as a string.
* @param motion The motion to read the changes from.
* @result A string containing a list of commands.
*/
static AZStd::vector<MCore::Command*> GenerateMotionMetaData(EMotionFX::Motion* motion);
/**
* Use the given list , prepare it for the given motion and apply the meta data.
* @param motion The motion to apply the meta data on.
@@ -5,6 +5,13 @@
*
*/
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/JSON/rapidjson.h>
#include <AzCore/JSON/document.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/FileFunc/FileFunc.h>
#include "Exporter.h"
#include <MCore/Source/ReflectionSerializer.h>
#include <EMotionFX/Source/MotionEvent.h>
@@ -28,17 +35,38 @@ namespace ExporterLib
return;
}
AZ::Outcome<AZStd::string> serializedMotionEventTable = MCore::ReflectionSerializer::Serialize(motionEventTable);
if (!serializedMotionEventTable.IsSuccess())
AZ::SerializeContext* context = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
if (!context)
{
AZ_Error("EMotionFX", false, "Can't save motion events. Can't get serialize context from component application.");
return;
}
const size_t serializedTableSizeInBytes = serializedMotionEventTable.GetValue().size();
AZ::JsonSerializerSettings settings;
settings.m_serializeContext = context;
rapidjson::Document jsonDocument;
auto jsonResult = AZ::JsonSerialization::Store(jsonDocument, jsonDocument.GetAllocator(), *motionEventTable, settings);
if (jsonResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
{
AZ_Error("EMotionFX", false, "JSON serialization failed: %s", jsonResult.ToString("").c_str());
return;
}
AZStd::string serializedMotionEventTable;
auto writeToStringOutcome = AzFramework::FileFunc::WriteJsonToString(jsonDocument, serializedMotionEventTable);
if (!writeToStringOutcome.IsSuccess())
{
AZ_Error("EMotionFX", false, "WriteJsonToString failed: %s", writeToStringOutcome.GetError().c_str());
return;
}
const size_t serializedTableSizeInBytes = serializedMotionEventTable.size();
// the motion event table chunk header
EMotionFX::FileFormat::FileChunk chunkHeader;
chunkHeader.mChunkID = EMotionFX::FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE;
chunkHeader.mVersion = 2;
chunkHeader.mVersion = 3;
chunkHeader.mSizeInBytes = static_cast<uint32>(serializedTableSizeInBytes + sizeof(EMotionFX::FileFormat::FileMotionEventTableSerialized));
@@ -51,6 +79,6 @@ namespace ExporterLib
// save the chunk header and the chunk
file->Write(&chunkHeader, sizeof(EMotionFX::FileFormat::FileChunk));
file->Write(&tableHeader, sizeof(EMotionFX::FileFormat::FileMotionEventTableSerialized));
file->Write(serializedMotionEventTable.GetValue().c_str(), serializedTableSizeInBytes);
file->Write(serializedMotionEventTable.c_str(), serializedTableSizeInBytes);
}
} // namespace ExporterLib
@@ -10,6 +10,7 @@
#include <SceneAPI/SceneCore/Events/ExportProductList.h>
#include <SceneAPIExt/Rules/MetaDataRule.h>
#include <SceneAPIExt/Rules/MotionMetaDataRule.h>
#include <SceneAPIExt/Groups/IMotionGroup.h>
#include <RCExt/Motion/MotionGroupExporter.h>
#include <RCExt/ExportContexts.h>
@@ -72,7 +73,7 @@ namespace EMotionFX
result += SceneEvents::Process<MotionDataBuilderContext>(dataBuilderContext, AZ::RC::Phase::Filling);
result += SceneEvents::Process<MotionDataBuilderContext>(dataBuilderContext, AZ::RC::Phase::Finalizing);
// Check if there is meta data and apply it to the motion.
// Legacy meta data: Check if there is legacy (XML) event data rule and apply it.
AZStd::vector<MCore::Command*> metaDataCommands;
if (Rule::MetaDataRule::LoadMetaData(motionGroup, metaDataCommands))
{
@@ -82,6 +83,14 @@ namespace EMotionFX
}
}
// Apply motion meta data.
AZStd::shared_ptr<EMotionFX::Pipeline::Rule::MotionMetaData> motionMetaData;
if (EMotionFX::Pipeline::Rule::LoadFromGroup<EMotionFX::Pipeline::Rule::MotionMetaDataRule>(motionGroup, motionMetaData))
{
motion->SetEventTable(motionMetaData->GetClonedEventTable(motion));
motion->SetMotionExtractionFlags(motionMetaData->GetMotionExtractionFlags());
}
ExporterLib::SaveMotion(filename, motion, MCore::Endian::ENDIAN_LITTLE);
static AZ::Data::AssetType emotionFXMotionAssetType("{00494B8E-7578-4BA2-8B28-272E90680787}"); // from MotionAsset.h in EMotionFX Gem
context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), emotionFXMotionAssetType,
@@ -17,12 +17,13 @@
#include <SceneAPIExt/Behaviors/MotionGroupBehavior.h>
#include <SceneAPIExt/Groups/MotionGroup.h>
#include <SceneAPIExt/Rules/MotionScaleRule.h>
#include <SceneAPIExt/Rules/MotionAdditiveRule.h>
#include <SceneAPIExt/Rules/MotionCompressionSettingsRule.h>
#include <SceneAPIExt/Rules/MotionMetaDataRule.h>
#include <SceneAPIExt/Rules/MotionSamplingRule.h>
#include <SceneAPIExt/Rules/MotionScaleRule.h>
#include <SceneAPIExt/Rules/MotionRangeRule.h>
#include <SceneAPIExt/Rules/MorphTargetRule.h>
#include <SceneAPIExt/Rules/MotionAdditiveRule.h>
#include <SceneAPIExt/Rules/MotionSamplingRule.h>
namespace EMotionFX
{
@@ -35,11 +36,13 @@ namespace EMotionFX
void MotionGroupBehavior::Reflect(AZ::ReflectContext* context)
{
Group::MotionGroup::Reflect(context);
Rule::MotionScaleRule::Reflect(context);
Rule::MotionCompressionSettingsRule::Reflect(context);
Rule::MorphTargetRuleReadOnly::Reflect(context);
Rule::MotionAdditiveRule::Reflect(context);
Rule::MotionCompressionSettingsRule::Reflect(context);
Rule::MotionMetaData::Reflect(context);
Rule::MotionMetaDataRule::Reflect(context);
Rule::MotionSamplingRule::Reflect(context);
Rule::MotionScaleRule::Reflect(context);
Rule::MorphTargetRuleReadOnly::Reflect(context);
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
@@ -16,9 +16,11 @@
#include <SceneAPIExt/Rules/MetaDataRule.h>
#include <SceneAPIExt/Rules/MotionRangeRule.h>
#include <SceneAPIExt/Rules/MotionCompressionSettingsRule.h>
#include <SceneAPIExt/Rules/MotionMetaDataRule.h>
#include <SceneAPIExt/Rules/MotionSamplingRule.h>
#include <SceneAPIExt/Groups/MotionGroup.h>
#include <EMotionFX/CommandSystem/Source/MetaData.h>
#include <EMotionFX/Source/MotionData/NonUniformMotionData.h>
namespace EMotionFX
@@ -89,7 +91,7 @@ namespace EMotionFX
serializeContext->Class<IMotionGroup, AZ::SceneAPI::DataTypes::IGroup>()->Version(1);
serializeContext->Class<MotionGroup, IMotionGroup>()->Version(5, VersionConverter)
serializeContext->Class<MotionGroup, IMotionGroup>()->Version(6, VersionConverter)
->Field("name", &MotionGroup::m_name)
->Field("selectedRootBone", &MotionGroup::m_selectedRootBone)
->Field("id", &MotionGroup::m_id)
@@ -225,6 +227,60 @@ namespace EMotionFX
}
}
// Motion meta data introduced (no more string- or object-based commands stored in the former meta data rule)
if (version < 6)
{
AZ::SerializeContext::DataElementNode* ruleContainerNode = classElement.FindSubElement(AZ_CRC("rules", 0x899a993c));
if (!ruleContainerNode)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rule container.\n");
return false;
}
AZ::SerializeContext::DataElementNode* rulesNode = ruleContainerNode->FindSubElement(AZ_CRC("rules", 0x899a993c));
if (!rulesNode)
{
AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rules within rule container.\n");
return false;
}
const int numRules = rulesNode->GetNumSubElements();
for (int i = 0; i < numRules; ++i)
{
AZ::SerializeContext::DataElementNode& sharedPointerNode = rulesNode->GetSubElement(i);
if (sharedPointerNode.GetNumSubElements() == 1)
{
AZ::SerializeContext::DataElementNode& currentRuleNode = sharedPointerNode.GetSubElement(0);
if (currentRuleNode.GetId() == azrtti_typeid<Rule::MetaDataRule>())
{
// Read the old, command-based meta data rule and retrieve the command objects.
Rule::MetaDataRule oldMetaDataRule;
currentRuleNode.GetData<Rule::MetaDataRule>(oldMetaDataRule);
const AZStd::vector<MCore::Command*>& commands = oldMetaDataRule.GetMetaData<const AZStd::vector<MCore::Command*>&>();
// Apply the commands onto a temporary motion.
auto motion = new EMotionFX::Motion("");
motion->SetMotionData(aznew EMotionFX::NonUniformMotionData());
CommandSystem::MetaData::ApplyMetaDataOnMotion(motion, commands);
// Construct the new motion meta data rule.
auto metaData = AZStd::make_shared<EMotionFX::Pipeline::Rule::MotionMetaData>(motion->GetMotionExtractionFlags(), motion->GetEventTable());
auto metaDataRule = AZStd::make_shared<EMotionFX::Pipeline::Rule::MotionMetaDataRule>(metaData);
// Add the new motion meta data rule.
AZ::SceneAPI::Containers::RuleContainer ruleContainer;
ruleContainerNode->GetDataHierarchy<AZ::SceneAPI::Containers::RuleContainer>(context, ruleContainer);
ruleContainer.RemoveRule(i);
ruleContainer.AddRule(metaDataRule);
ruleContainerNode->SetData(context, ruleContainer);
motion->Destroy();
break;
}
}
}
}
return result;
}
}
@@ -35,7 +35,7 @@ namespace EMotionFX
return false;
}
outData = rule->GetData();
outData = AZStd::move(rule->GetData());
return true;
}
@@ -57,7 +57,7 @@ namespace EMotionFX
/**
* Set the meta data string which contains a list of commands representing the changes the user did on the source asset.
* This string can be constructed using CommandSystem::GenerateMotionMetaData() and CommandSystem::GenerateActorMetaData().
* This string can be constructed using CommandSystem::GenerateActorMetaData().
* @param metaData The meta data string containing a list of commands to be applied on the source asset.
*/
void SetMetaData(const AZStd::string& metaData);
@@ -0,0 +1,84 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <SceneAPI/SceneCore/DataTypes/Groups/IGroup.h>
#include <SceneAPI/SceneCore/Events/ManifestMetaInfoBus.h>
#include <SceneAPIExt/Rules/MotionMetaDataRule.h>
namespace EMotionFX::Pipeline::Rule
{
void MotionMetaData::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (!serializeContext)
{
return;
}
serializeContext->Class<MotionMetaData>()
->Version(1)
->Field("motionEventTable", &MotionMetaData::m_motionEventTable)
->Field("motionExtractionFlags", &MotionMetaData::m_motionExtractionFlags)
;
}
MotionMetaData::MotionMetaData(EMotionFX::EMotionExtractionFlags extractionFlags, EMotionFX::MotionEventTable* eventTable)
: m_motionExtractionFlags(extractionFlags)
{
m_motionEventTable = CloneMotionEventTable(eventTable);
}
MotionMetaData::MotionMetaData()
: m_motionExtractionFlags(static_cast<EMotionFX::EMotionExtractionFlags>(0))
{
}
AZStd::unique_ptr<EMotionFX::MotionEventTable> MotionMetaData::GetClonedEventTable(EMotionFX::Motion* targetMotion) const
{
AZStd::unique_ptr<EMotionFX::MotionEventTable> clonedEventTable = CloneMotionEventTable(m_motionEventTable.get());
clonedEventTable->InitAfterLoading(targetMotion);
return clonedEventTable;
}
AZStd::unique_ptr<EMotionFX::MotionEventTable> MotionMetaData::CloneMotionEventTable(EMotionFX::MotionEventTable* sourceEventTable)
{
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
if (!serializeContext)
{
AZ_Error("EMotionFX", false, "Cannot clone motion event table for motion meta data. Can't get serialize context from component application.");
return {};
}
AZStd::unique_ptr<EMotionFX::MotionEventTable> clonedEventTable(serializeContext->CloneObject<EMotionFX::MotionEventTable>(sourceEventTable));
return clonedEventTable;
}
MotionMetaDataRule::MotionMetaDataRule()
: ExternalToolRule<AZStd::shared_ptr<MotionMetaData>>()
{
}
MotionMetaDataRule::MotionMetaDataRule(const AZStd::shared_ptr<MotionMetaData>& data)
: m_data(data)
{
}
void MotionMetaDataRule::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<MotionMetaDataRule>()
->Version(1)
->Field("data", &MotionMetaDataRule::m_data)
;
}
}
} // EMotionFX::Pipeline::Rule
@@ -0,0 +1,59 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <EMotionFX/Source/MotionEventTable.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/IRule.h>
#include <SceneAPI/SceneData/SceneDataConfiguration.h>
#include <SceneAPIExt/Rules/ExternalToolRule.h>
namespace EMotionFX::Pipeline::Rule
{
struct MotionMetaData
{
AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaData, "{A381A915-3CB3-4F60-82B3-70865CFA1F4F}");
AZ_CLASS_ALLOCATOR(MotionMetaData, AZ::SystemAllocator, 0)
MotionMetaData();
MotionMetaData(EMotionFX::EMotionExtractionFlags extractionFlags, EMotionFX::MotionEventTable* eventTable);
virtual ~MotionMetaData() = default;
EMotionFX::EMotionExtractionFlags GetMotionExtractionFlags() const { return m_motionExtractionFlags; }
AZStd::unique_ptr<EMotionFX::MotionEventTable> GetClonedEventTable(EMotionFX::Motion* targetMotion) const;
static void Reflect(AZ::ReflectContext* context);
private:
static AZStd::unique_ptr<EMotionFX::MotionEventTable> CloneMotionEventTable(EMotionFX::MotionEventTable* sourceEventTable);
EMotionFX::EMotionExtractionFlags m_motionExtractionFlags;
AZStd::unique_ptr<EMotionFX::MotionEventTable> m_motionEventTable;
};
class MotionMetaDataRule
: public ExternalToolRule<AZStd::shared_ptr<MotionMetaData>>
{
public:
AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaDataRule, "{E68D0C3D-CBFF-4536-95C1-676474B351A5}", AZ::SceneAPI::DataTypes::IRule);
AZ_CLASS_ALLOCATOR(MotionMetaDataRule, AZ::SystemAllocator, 0)
MotionMetaDataRule();
MotionMetaDataRule(const AZStd::shared_ptr<MotionMetaData>& data);
~MotionMetaDataRule() final = default;
const AZStd::shared_ptr<MotionMetaData>& GetData() const override { return m_data; }
void SetData(const AZStd::shared_ptr<MotionMetaData>& data) override { m_data = data; }
static void Reflect(AZ::ReflectContext* context);
private:
AZStd::shared_ptr<MotionMetaData> m_data;
};
} // EMotionFX::Pipeline::Rule
@@ -37,6 +37,8 @@ set(FILES
Rules/IMotionCompressionSettingsRule.h
Rules/MotionCompressionSettingsRule.h
Rules/MotionCompressionSettingsRule.cpp
Rules/MotionMetaDataRule.h
Rules/MotionMetaDataRule.cpp
Rules/IMotionScaleRule.h
Rules/MotionScaleRule.h
Rules/MotionScaleRule.cpp
@@ -15,6 +15,16 @@ namespace EMotionFX
{
AZ_CLASS_ALLOCATOR_IMPL(Event, MotionEventAllocator, 0)
Event::Event(EventDataPtr&& data)
: m_eventDatas{ AZStd::move(data) }
{
}
Event::Event(EventDataSet&& datas)
: m_eventDatas(AZStd::move(datas))
{
}
void Event::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
+3 -10
View File
@@ -27,16 +27,9 @@ namespace EMotionFX
AZ_RTTI(Event, "{67549E9F-8E3F-4336-BDB8-716AFCBD4985}");
AZ_CLASS_ALLOCATOR_DECL
Event(EventDataPtr&& data = nullptr)
: m_eventDatas{AZStd::move(data)}
{
}
Event(EventDataSet&& datas)
: m_eventDatas(AZStd::move(datas))
{
}
Event() = default;
explicit Event(EventDataPtr&& data);
explicit Event(EventDataSet&& datas);
virtual ~Event() = default;
static void Reflect(AZ::ReflectContext* context);
@@ -6,10 +6,17 @@
*/
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/JSON/rapidjson.h>
#include <AzCore/JSON/document.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzCore/Serialization/Json/RegistrationContext.h>
#include <AzCore/Serialization/Json/JsonSerialization.h>
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
#include <AzFramework/FileFunc/FileFunc.h>
#include <EMotionFX/Source/Parameter/GroupParameter.h>
#include <EMotionFX/Source/Parameter/ParameterFactory.h>
#include <MCore/Source/AttributeFactory.h>
@@ -1161,10 +1168,11 @@ namespace EMotionFX
AZStd::vector<char> buffer(fileEventTable.m_size);
file->Read(&buffer[0], fileEventTable.m_size);
MotionEventTable* motionEventTable = AZ::Utils::LoadObjectFromBuffer<MotionEventTable>(&buffer[0], buffer.size(), context);
auto motionEventTable = AZStd::unique_ptr<MotionEventTable>(AZ::Utils::LoadObjectFromBuffer<MotionEventTable>(&buffer[0], buffer.size(), context));
if (motionEventTable)
{
motionEventTable->InitAfterLoading(motion);
motion->SetEventTable(AZStd::move(motionEventTable));
motion->GetEventTable()->InitAfterLoading(motion);
return true;
}
@@ -1173,6 +1181,57 @@ namespace EMotionFX
//=================================================================================================
bool ChunkProcessorMotionEventTrackTable3::Process(MCore::File* file, Importer::ImportParameters& importParams)
{
Motion* motion = importParams.mMotion;
MCORE_ASSERT(motion);
FileFormat::FileMotionEventTableSerialized fileEventTable;
file->Read(&fileEventTable, sizeof(FileFormat::FileMotionEventTableSerialized));
if (GetLogging())
{
MCore::LogDetailedInfo("- Motion Event Table:");
MCore::LogDetailedInfo(" + size = %d", fileEventTable.m_size);
}
AZStd::vector<char> buffer(fileEventTable.m_size);
file->Read(&buffer[0], fileEventTable.m_size);
AZStd::string_view bufferStringView(&buffer[0], buffer.size());
auto readJsonOutcome = AzFramework::FileFunc::ReadJsonFromString(bufferStringView);
AZStd::string errorMsg;
if (!readJsonOutcome.IsSuccess())
{
AZ_Error("EMotionFX", false, "Loading motion event table failed due to ReadJsonFromString. %s", readJsonOutcome.TakeError().c_str());
return false;
}
rapidjson::Document document = readJsonOutcome.TakeValue();
AZ::SerializeContext* context = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
if (!context)
{
return false;
}
AZ::JsonDeserializerSettings settings;
settings.m_serializeContext = context;
MotionEventTable* motionEventTable = motion->GetEventTable();
AZ::JsonSerializationResult::ResultCode jsonResult = AZ::JsonSerialization::Load(*motionEventTable, document, settings);
if (jsonResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted)
{
AZ_Error("EMotionFX", false, "Loading motion event table failed due to AZ::JsonSerialization::Load.");
return false;
}
motionEventTable->InitAfterLoading(motion);
return true;
}
//=================================================================================================
bool ChunkProcessorActorInfo::Process(MCore::File* file, Importer::ImportParameters& importParams)
{
const MCore::Endian::EEndianType endianType = importParams.mEndianType;
@@ -312,6 +312,7 @@ namespace EMotionFX
// shared file format chunk processors
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 1)
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable2, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 2)
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable3, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 3)
// Actor file format chunk processors
EMFX_CHUNKPROCESSOR(ChunkProcessorActorInfo, FileFormat::ACTOR_CHUNK_INFO, 1)
@@ -1061,6 +1061,7 @@ namespace EMotionFX
// shared processors
RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable());
RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable2());
RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable3());
// Actor file format
RegisterChunkProcessor(aznew ChunkProcessorActorInfo());
@@ -26,29 +26,20 @@ namespace EMotionFX
{
AZ_CLASS_ALLOCATOR_IMPL(Motion, MotionAllocator, 0)
// constructor
Motion::Motion(const char* name)
: BaseObject()
{
mCustomData = nullptr;
mNameID = MCORE_INVALIDINDEX32;
mID = MCore::GetIDGenerator().GenerateID();
mEventTable = aznew MotionEventTable();
mUnitType = GetEMotionFX().GetUnitType();
mFileUnitType = mUnitType;
mExtractionFlags = static_cast<EMotionExtractionFlags>(0);
m_motionData = nullptr;
mID = MCore::GetIDGenerator().GenerateID();
m_eventTable = AZStd::make_unique<MotionEventTable>();
mUnitType = GetEMotionFX().GetUnitType();
mFileUnitType = mUnitType;
mExtractionFlags = static_cast<EMotionExtractionFlags>(0);
if (name)
{
SetName(name);
}
mMotionFPS = 30.0f;
mDirtyFlag = false;
mAutoUnregister = true;
#if defined(EMFX_DEVELOPMENT_BUILD)
mIsOwnedByRuntime = false;
#endif // EMFX_DEVELOPMENT_BUILD
@@ -57,8 +48,6 @@ namespace EMotionFX
GetMotionManager().AddMotion(this);
}
// destructor
Motion::~Motion()
{
// trigger the OnDeleteMotion event
@@ -70,11 +59,6 @@ namespace EMotionFX
GetMotionManager().RemoveMotion(this, false);
}
if (mEventTable)
{
mEventTable->Destroy();
}
delete m_motionData;
}
@@ -208,19 +192,14 @@ namespace EMotionFX
MotionEventTable* Motion::GetEventTable() const
{
return mEventTable;
return m_eventTable.get();
}
void Motion::SetEventTable(MotionEventTable* newTable)
void Motion::SetEventTable(AZStd::unique_ptr<MotionEventTable> eventTable)
{
if (mEventTable && mEventTable != newTable)
{
mEventTable->Destroy();
}
mEventTable = newTable;
m_eventTable = AZStd::move(eventTable);
}
void Motion::SetID(uint32 id)
{
mID = id;
+10 -10
View File
@@ -7,7 +7,7 @@
#pragma once
// include the required headers
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include "EMotionFXConfig.h"
#include "EMotionFXManager.h"
#include "PlayBackInfo.h"
@@ -115,7 +115,7 @@ namespace EMotionFX
* Set the event table.
* @param newTable The new motion event table for the Motion to use.
*/
void SetEventTable(MotionEventTable* newTable);
void SetEventTable(AZStd::unique_ptr<MotionEventTable> eventTable);
/**
* Set the motion framerate.
@@ -249,19 +249,19 @@ namespace EMotionFX
void SetMotionData(MotionData* motionData, bool delOldFromMem=true);
protected:
MotionData* m_motionData; /**< The motion data, which can in theory be any data representation/compression. */
MotionData* m_motionData = nullptr; /**< The motion data, which can in theory be any data representation/compression. */
AZStd::string mFileName; /**< The filename of the motion. */
PlayBackInfo m_defaultPlayBackInfo; /**< The default/fallback motion playback info which will be used when no playback info is passed to the Play() function. */
MotionEventTable* mEventTable; /**< The event table, which contains all events, and will make sure events get executed. */
AZStd::unique_ptr<MotionEventTable> m_eventTable; /**< The event table, which contains all events, and will make sure events get executed. */
MCore::Distance::EUnitType mUnitType; /**< The type of units used. */
MCore::Distance::EUnitType mFileUnitType; /**< The type of units used, inside the file that got loaded. */
void* mCustomData; /**< A pointer to custom user data that is linked with this motion object. */
float mMotionFPS; /**< The number of keyframes per second. */
uint32 mNameID; /**< The ID represention the name or description of this motion. */
uint32 mID; /**< The unique identification number for the motion. */
void* mCustomData = nullptr; /**< A pointer to custom user data that is linked with this motion object. */
float mMotionFPS = 30.0f; /**< The number of keyframes per second. */
uint32 mNameID = MCORE_INVALIDINDEX32; /**< The ID represention the name or description of this motion. */
uint32 mID = MCORE_INVALIDINDEX32; /**< The unique identification number for the motion. */
EMotionExtractionFlags mExtractionFlags; /**< The motion extraction flags, which define behavior of the motion extraction system when applied to this motion. */
bool mDirtyFlag; /**< The dirty flag which indicates whether the user has made changes to the motion since the last file save operation. */
bool mAutoUnregister; /**< Automatically unregister the motion from the motion manager when this motion gets deleted? Default is true. */
bool mDirtyFlag = false; /**< The dirty flag which indicates whether the user has made changes to the motion since the last file save operation. */
bool mAutoUnregister = true; /**< Automatically unregister the motion from the motion manager when this motion gets deleted? Default is true. */
#if defined(EMFX_DEVELOPMENT_BUILD)
bool mIsOwnedByRuntime;
@@ -5,7 +5,6 @@
*
*/
// include the required headers
#include "MotionEventTable.h"
#include "MotionEvent.h"
#include "MotionEventTrack.h"
@@ -19,22 +18,11 @@ namespace EMotionFX
{
AZ_CLASS_ALLOCATOR_IMPL(MotionEventTable, MotionEventAllocator, 0)
// constructor
MotionEventTable::MotionEventTable()
: BaseObject()
, m_syncTrack(nullptr)
{
}
// destructor
MotionEventTable::~MotionEventTable()
{
RemoveAllTracks();
}
void MotionEventTable::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@@ -56,7 +44,6 @@ namespace EMotionFX
track->SetMotion(motion);
}
motion->SetEventTable(this);
AutoCreateSyncTrack(motion);
}
@@ -96,7 +83,7 @@ namespace EMotionFX
{
for (MotionEventTrack* track : m_tracks)
{
track->Destroy();
delete track;
}
}
@@ -109,7 +96,7 @@ namespace EMotionFX
{
if (delFromMem)
{
m_tracks[index]->Destroy();
delete m_tracks[index];
}
m_tracks.erase(AZStd::next(m_tracks.begin(), index));
@@ -196,9 +183,8 @@ namespace EMotionFX
AnimGraphSyncTrack* syncTrack;
if (!track)
{
// create and add the sync track
syncTrack = aznew AnimGraphSyncTrack("Sync", motion);
AddTrack(syncTrack);
InsertTrack(0, syncTrack);
}
else
{
@@ -7,9 +7,7 @@
#pragma once
// include the required headers
#include "EMotionFXConfig.h"
#include "BaseObject.h"
#include "AnimGraphSyncTrack.h"
#include <AzCore/std/containers/vector.h>
@@ -40,17 +38,15 @@ namespace EMotionFX
* The handling of those events is done by the MotionEventHandler class that you specify to the MotionEventManager singleton.
*/
class EMFX_API MotionEventTable
: public BaseObject
{
friend class MotionEvent;
public:
AZ_CLASS_ALLOCATOR_DECL
AZ_RTTI(MotionEventTable, "{DB5BF142-99BE-4026-8D3E-3E5B30C14714}", BaseObject)
AZ_RTTI(MotionEventTable, "{DB5BF142-99BE-4026-8D3E-3E5B30C14714}")
MotionEventTable();
~MotionEventTable();
MotionEventTable() = default;
virtual ~MotionEventTable();
static void Reflect(AZ::ReflectContext* context);
@@ -100,7 +96,6 @@ namespace EMotionFX
AZStd::vector<MotionEventTrack*> m_tracks;
/// A shortcut to the track containing sync events.
AnimGraphSyncTrack* m_syncTrack;
AnimGraphSyncTrack* m_syncTrack = nullptr;
};
} // namespace EMotionFX
@@ -5,7 +5,6 @@
*
*/
// include the required headers
#include "MotionEventTrack.h"
#include "MotionEvent.h"
#include "EventManager.h"
@@ -20,30 +19,19 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
namespace EMotionFX
{
AZ_CLASS_ALLOCATOR_IMPL(MotionEventTrack, MotionEventAllocator, 0)
// constructor
MotionEventTrack::MotionEventTrack(Motion* motion)
: BaseObject()
, mMotion(motion)
, mNameID(MCORE_INVALIDINDEX32)
, mEnabled(true)
, mDeletable(true)
: mMotion(motion)
{
}
// extended constructor
MotionEventTrack::MotionEventTrack(const char* name, Motion* motion)
: BaseObject()
, mMotion(motion)
, mEnabled(true)
, mDeletable(true)
: mMotion(motion)
, m_name(name)
{
SetName(name);
}
MotionEventTrack::MotionEventTrack(const MotionEventTrack& other)
@@ -59,7 +47,7 @@ namespace EMotionFX
}
m_events = other.m_events;
mMotion = other.mMotion;
mNameID = other.mNameID;
m_name = other.m_name;
return *this;
}
@@ -72,8 +60,8 @@ namespace EMotionFX
}
serializeContext->Class<MotionEventTrack>()
->Version(1)
->Field("name", &MotionEventTrack::mNameID)
->Version(2, VersionConverter)
->Field("name", &MotionEventTrack::m_name)
->Field("enabled", &MotionEventTrack::mEnabled)
->Field("deletable", &MotionEventTrack::mDeletable)
->Field("events", &MotionEventTrack::m_events)
@@ -94,6 +82,31 @@ namespace EMotionFX
;
}
bool MotionEventTrack::VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement)
{
const unsigned int version = classElement.GetVersion();
if (version < 2)
{
int nameElementIndex = classElement.FindElement(AZ_CRC_CE("name"));
if (nameElementIndex < 0)
{
return false;
}
AZ::SerializeContext::DataElementNode& nameElement = classElement.GetSubElement(nameElementIndex);
MCore::StringIdPoolIndex oldName;
const bool result = nameElement.GetData<MCore::StringIdPoolIndex>(oldName);
classElement.RemoveElement(nameElementIndex);
if (result)
{
AZStd::string newName = MCore::GetStringIdPool().GetName(oldName.m_index);
classElement.AddElementWithData(context, "name", newName);
}
}
return true;
}
// creation
MotionEventTrack* MotionEventTrack::Create(Motion* motion)
@@ -112,7 +125,7 @@ namespace EMotionFX
// set the name of the motion event track
void MotionEventTrack::SetName(const char* name)
{
mNameID = MCore::GetStringIdPool().GenerateIdForString(name);
m_name = name;
}
@@ -362,60 +375,31 @@ namespace EMotionFX
RemoveAllEvents();
}
// get the name
const char* MotionEventTrack::GetName() const
{
if (mNameID == MCORE_INVALIDINDEX32)
{
return "";
}
return MCore::GetStringIdPool().GetName(mNameID).c_str();
return m_name.c_str();
}
// get the name as string object
const AZStd::string& MotionEventTrack::GetNameString() const
{
if (mNameID == MCORE_INVALIDINDEX32)
{
return MCore::GetStringIdPool().GetName(0);
}
return MCore::GetStringIdPool().GetName(mNameID);
return m_name;
}
// copy the track contents to a target track
// this overwrites all existing contents of the target track
void MotionEventTrack::CopyTo(MotionEventTrack* targetTrack) const
{
targetTrack->mNameID = mNameID;
targetTrack->m_name = m_name;
targetTrack->m_events = m_events;
targetTrack->mEnabled = mEnabled;
}
// reserve memory for a given amount of events
void MotionEventTrack::ReserveNumEvents(size_t numEvents)
{
m_events.reserve(numEvents);
}
uint32 MotionEventTrack::GetNameID() const
{
return mNameID;
}
void MotionEventTrack::SetNameID(uint32 id)
{
mNameID = id;
}
void MotionEventTrack::SetIsEnabled(bool enabled)
{
mEnabled = enabled;
@@ -7,13 +7,10 @@
#pragma once
// include the required headers
#include <AzCore/std/containers/vector.h>
#include "EMotionFXConfig.h"
#include "BaseObject.h"
#include "MotionEvent.h"
#include <MCore/Source/StringIdPool.h>
#include <AzCore/std/containers/vector.h>
namespace AZ
{
@@ -38,15 +35,15 @@ namespace EMotionFX
* The handling of those events is done by the MotionEventHandler class that you specify to the MotionEventManager singleton.
*/
class EMFX_API MotionEventTrack
: public BaseObject
{
friend class MotionEvent;
public:
AZ_RTTI(MotionEventTrack, "{D142399D-C7DF-4E4A-A099-7E4E662F1E81}", BaseObject)
AZ_RTTI(MotionEventTrack, "{D142399D-C7DF-4E4A-A099-7E4E662F1E81}")
AZ_CLASS_ALLOCATOR_DECL
MotionEventTrack() {}
MotionEventTrack() = default;
virtual ~MotionEventTrack() = default;
/**
* The constructor.
@@ -167,8 +164,6 @@ namespace EMotionFX
const char* GetName() const;
const AZStd::string& GetNameString() const;
uint32 GetNameID() const;
void SetNameID(uint32 id);
void SetIsEnabled(bool enabled);
bool GetIsEnabled() const;
@@ -182,23 +177,22 @@ namespace EMotionFX
void ReserveNumEvents(size_t numEvents);
protected:
/// The collection of motion events.
AZStd::vector<MotionEvent> m_events;
AZStd::string m_name;
/// The motion where this track belongs to.
Motion* mMotion;
/// The name ID.
MCore::StringIdPoolIndex mNameID;
/// Is this track enabled?
bool mEnabled;
bool mDeletable;
bool mEnabled = true;
bool mDeletable = true;
private:
void ProcessEventsImpl(float startTime, float endTime, ActorInstance* actorInstance, const MotionInstance* motionInstance, const AZStd::function<void(EMotionFX::EventInfo&)>& processFunc);
template <typename Functor>
void ExtractEvents(float startTime, float endTime, const MotionInstance* motionInstance, const Functor& processFunc, bool handleLoops = true) const;
static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement);
};
} // namespace EMotionFX
@@ -298,14 +298,20 @@ namespace EMotionFX
{
Physics::CapsuleShapeConfiguration* capsule = static_cast<Physics::CapsuleShapeConfiguration*>(collider.second.get());
capsule->m_height = boneDirection.GetLength();
collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized());
if (AZ::IsClose(localBoneDirection.GetLength(), 1.0f))
{
collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized());
}
capsule->m_height = boneLength;
const float radius = AZ::GetMin(rootMeanSquareDistanceFromBone, minRadiusRatio * boneLength);
capsule->m_radius = radius;
}
else if (colliderType == azrtti_typeid<Physics::BoxShapeConfiguration>())
{
collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized());
if (AZ::IsClose(localBoneDirection.GetLength(), 1.0f))
{
collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized());
}
Physics::BoxShapeConfiguration* box = static_cast<Physics::BoxShapeConfiguration*>(collider.second.get());
box->m_dimensions = AZ::Vector3(2.0f * rootMeanSquareDistanceFromBone, 2.0f * rootMeanSquareDistanceFromBone, boneLength);
}
@@ -22,6 +22,7 @@
#include <SceneAPIExt/Rules/ActorPhysicsSetupRule.h>
#include <SceneAPIExt/Rules/SimulatedObjectSetupRule.h>
#include <SceneAPIExt/Rules/MetaDataRule.h>
#include <SceneAPIExt/Rules/MotionMetaDataRule.h>
#include <SceneAPIExt/Groups/MotionGroup.h>
#include <SceneAPIExt/Groups/ActorGroup.h>
@@ -293,16 +294,63 @@ namespace EMStudio
AZStd::string sourceAssetFilename;
EBUS_EVENT_RESULT(fullPathFound, AzToolsFramework::AssetSystemRequestBus, GetFullSourcePathFromRelativeProductPath, productFilename, sourceAssetFilename);
// Generate meta data command for all changes being made to the motion.
const AZStd::vector<MCore::Command*> metaData = CommandSystem::MetaData::GenerateMotionMetaData(motion);
// Load the manifest from disk.
AZStd::shared_ptr<AZ::SceneAPI::Containers::Scene> scene;
AZ::SceneAPI::Events::SceneSerializationBus::BroadcastResult(scene, &AZ::SceneAPI::Events::SceneSerializationBus::Events::LoadScene, sourceAssetFilename, AZ::Uuid::CreateNull());
if (!scene)
{
AZ_Error("EMotionFX", false, "Unable to save meta data to manifest due to failed scene loading.");
return false;
}
// Save meta data commands to the manifest.
const bool saveResult = EMotionFX::Pipeline::Rule::MetaDataRule::SaveMetaDataToFile<EMotionFX::Pipeline::Group::MotionGroup>(sourceAssetFilename, groupName, metaData, outResult);
AZ::SceneAPI::Containers::SceneManifest& manifest = scene->GetManifest();
auto values = manifest.GetValueStorage();
auto groupView = AZ::SceneAPI::Containers::MakeDerivedFilterView<EMotionFX::Pipeline::Group::MotionGroup>(values);
for (EMotionFX::Pipeline::Group::MotionGroup& group : groupView)
{
// Non-case sensitive group name comparison. Product filenames are lower case only and might mismatch casing of the entered group name.
if (AzFramework::StringFunc::Equal(group.GetName().c_str(), groupName.c_str()))
{
// Remove legacy meta data rule.
EMotionFX::Pipeline::Rule::RemoveRuleFromGroup<EMotionFX::Pipeline::Rule::MetaDataRule, const AZStd::vector<MCore::Command*>>(*scene, group);
// Add motion meta data.
auto motionMetaData = AZStd::make_shared<EMotionFX::Pipeline::Rule::MotionMetaData>(motion->GetMotionExtractionFlags(), motion->GetEventTable());
EMotionFX::Pipeline::Rule::SaveToGroup<EMotionFX::Pipeline::Rule::MotionMetaDataRule, AZStd::shared_ptr<EMotionFX::Pipeline::Rule::MotionMetaData>>(*scene, group, motionMetaData);
}
}
const AZStd::string& manifestFilename = scene->GetManifestFilename();
const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(manifestFilename.c_str());
// Source Control: Checkout file.
if (fileExisted)
{
using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus;
bool checkoutResult = false;
ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, manifestFilename.c_str(), "Checking out manifest from source control.", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {});
if (!checkoutResult)
{
AZ_Error("EMotionFX", false, "Cannot checkout file '%s' from source control.", manifestFilename.c_str());
return false;
}
}
const bool saveResult = manifest.SaveToFile(manifestFilename.c_str());
if (saveResult)
{
motion->SetDirtyFlag(false);
}
// Source Control: Add file in case it did not exist before (when saving it the first time).
if (saveResult && !fileExisted)
{
using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus;
bool checkoutResult = false;
ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, manifestFilename.c_str(), "Adding manifest to source control.", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {});
AZ_Error("EMotionFX", checkoutResult, "Cannot add file '%s' to source control.", manifestFilename.c_str());
}
return saveResult;
}
@@ -63,6 +63,8 @@ namespace EMotionFX
&actorSettings,
"");
// Set the is owned by runtime flag before finalizing the actor, as that uses the flag already.
assetData->m_emfxActor->SetIsOwnedByRuntime(true);
assetData->m_emfxActor->Finalize();
// Clear out the EMFX raw asset data.
@@ -74,8 +76,6 @@ namespace EMotionFX
return false;
}
assetData->m_emfxActor->SetIsOwnedByRuntime(true);
// Note: Render actor depends on the mesh asset, so we need to manually create it after mesh asset has been loaded.
return static_cast<bool>(assetData->m_emfxActor);
}
@@ -31,8 +31,8 @@ TEST_F(SystemComponentFixture, DISABLED_EventDataFactoryMakesUniqueData)
EXPECT_EQ(loadedTrack->GetEvent(0).GetEventDatas()[0], track->GetEvent(0).GetEventDatas()[0]);
EXPECT_EQ(loadedTrack->GetEvent(0).GetEventDatas()[0].use_count(), 2);
track->Destroy();
loadedTrack->Destroy();
delete track;
delete loadedTrack;
}
} // end namespace EMotionFX
@@ -202,12 +202,6 @@ namespace LyShine
LyShineAllocatorScope::DeactivateAllocators();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void LyShineSystemComponent::InitializeSystem()
{
BroadcastCursorImagePathname();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void LyShineSystemComponent::RegisterComponentTypeForMenuOrdering(const AZ::Uuid& typeUuid)
{
@@ -379,6 +373,8 @@ namespace LyShine
#endif
m_pLyShine = new CLyShine(gEnv->pSystem);
gEnv->pLyShine = m_pLyShine;
BroadcastCursorImagePathname();
}
void LyShineSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system)
@@ -60,7 +60,6 @@ namespace LyShine
////////////////////////////////////////////////////////////////////////
// UiSystemBus interface implementation
void InitializeSystem() override;
void RegisterComponentTypeForMenuOrdering(const AZ::Uuid& typeUuid) override;
const AZStd::vector<AZ::Uuid>* GetComponentTypesForMenuOrdering() override;
const AZStd::list<AZ::ComponentDescriptor*>* GetLyShineComponentDescriptors();
@@ -14,8 +14,10 @@
<Package InstallerVersion="301" Compressed="yes" InstallPrivileges="elevated" InstallScope="perMachine"/>
<!-- auto distribute the installable files across N cab files -->
<MediaTemplate EmbedCab="$(var.CPACK_EMBED_ARTIFACTS)"/>
<!-- auto distribute the install-able files across N cab files that are at most 350 MB in size -->
<MediaTemplate EmbedCab="$(var.CPACK_EMBED_ARTIFACTS)"
MaximumUncompressedMediaSize="350"
CompressionLevel="high"/>
<MajorUpgrade Schedule="afterInstallInitialize"
AllowSameVersionUpgrades="yes"
+5
View File
@@ -31,6 +31,11 @@ else
RUN_CONFIGURE=1
fi
fi
# temporarily enabling cmake regeneration for this platform
# We have observed cases where continous integration has not regenerated but a regeneration was required, leaving the build in a bad state
RUN_CONFIGURE=1
if [[ ! -z "$RUN_CONFIGURE" ]]; then
# have to use eval since $CMAKE_OPTIONS (${EXTRA_CMAKE_OPTIONS}) contains quotes that need to be processed
echo [ci_build] ${CONFIGURE_CMD}