Removed legacy chunk processors for anim graphs and motion sets together with unused shared data
Signed-off-by: Benjamin Jillich <jillich@amazon.com>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <MCore/Source/AttributeFactory.h>
|
||||
#include <MCore/Source/AzCoreConversions.h>
|
||||
#include <MCore/Source/Distance.h>
|
||||
#include <MCore/Source/File.h>
|
||||
#include <MCore/Source/ReflectionSerializer.h>
|
||||
#include <MCore/Source/StringConversions.h>
|
||||
#include <MCore/Source/MCoreSystem.h>
|
||||
@@ -53,7 +54,6 @@
|
||||
#include "../AnimGraphTransitionCondition.h"
|
||||
#include "../MCore/Source/Endian.h"
|
||||
#include "../NodeMap.h"
|
||||
#include "LegacyAnimGraphNodeParser.h"
|
||||
|
||||
#include <EMotionFX/Source/Importer/ActorFileFormat.h>
|
||||
#include <EMotionFX/Source/TwoStringEventData.h>
|
||||
@@ -245,14 +245,10 @@ namespace EMotionFX
|
||||
{
|
||||
mFileHighVersion = 1;
|
||||
mFileLowVersion = 0;
|
||||
mIsUnicodeFile = true;
|
||||
|
||||
// allocate the string buffer used for reading in variable sized strings
|
||||
mStringStorageSize = 256;
|
||||
mStringStorage = (char*)MCore::Allocate(mStringStorageSize, EMFX_MEMCATEGORY_IMPORTER);
|
||||
mBlendNodes.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER);
|
||||
mBlendNodes.Reserve(1024);
|
||||
//mConvertString.Reserve( 256 );
|
||||
}
|
||||
|
||||
|
||||
@@ -281,57 +277,8 @@ namespace EMotionFX
|
||||
|
||||
mStringStorage = nullptr;
|
||||
mStringStorageSize = 0;
|
||||
//mConvertString.Clear();
|
||||
|
||||
// get rid of the blend nodes array
|
||||
mBlendNodes.Clear();
|
||||
|
||||
m_entryNodeIndexToStateMachineIdLookupTable.clear();
|
||||
}
|
||||
|
||||
|
||||
// check if the strings in the file are encoded using unicode or multi-byte
|
||||
bool SharedHelperData::GetIsUnicodeFile(const char* dateString, MCore::Array<SharedData*>* sharedData)
|
||||
{
|
||||
// find the helper data
|
||||
SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID);
|
||||
SharedHelperData* helperData = static_cast<SharedHelperData*>(data);
|
||||
|
||||
AZStd::vector<AZStd::string> dateParts;
|
||||
AzFramework::StringFunc::Tokenize(dateString, dateParts, MCore::CharacterConstants::space, false /* keep empty strings */, true /* keep space strings */);
|
||||
|
||||
// decode the month
|
||||
int32 month = 0;
|
||||
const AZStd::string& monthString = dateParts[0];
|
||||
const char* monthStrings[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
for (int32 i = 0; i < 12; ++i)
|
||||
{
|
||||
if (monthString == monthStrings[i])
|
||||
{
|
||||
month = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//int32 day = dateParts[1].ToInt();
|
||||
int32 year;
|
||||
if (!AzFramework::StringFunc::LooksLikeInt(dateParts[2].c_str(), &year))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// set if the file contains unicode strings or not based on the compilcation date
|
||||
if (year < 2012 || (year == 2012 && month < 11))
|
||||
{
|
||||
helperData->mIsUnicodeFile = false;
|
||||
}
|
||||
|
||||
//LogInfo( "String: '%s', Decoded: %i.%i.%i - isUnicode=%i", dateString, day, month, year, helperData->mIsUnicodeFile );
|
||||
|
||||
return helperData->mIsUnicodeFile;
|
||||
}
|
||||
|
||||
|
||||
const char* SharedHelperData::ReadString(MCore::Stream* file, MCore::Array<SharedData*>* sharedData, MCore::Endian::EEndianType endianType)
|
||||
{
|
||||
MCORE_ASSERT(file);
|
||||
@@ -366,25 +313,6 @@ namespace EMotionFX
|
||||
return helperData->mStringStorage;
|
||||
}
|
||||
|
||||
|
||||
// get the array of anim graph nodes
|
||||
MCore::Array<AnimGraphNode*>& SharedHelperData::GetBlendNodes(MCore::Array<SharedData*>* sharedData)
|
||||
{
|
||||
// find the helper data
|
||||
SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID);
|
||||
SharedHelperData* helperData = static_cast<SharedHelperData*>(data);
|
||||
return helperData->mBlendNodes;
|
||||
}
|
||||
|
||||
// Get the table of entry state indices to state machines IDs
|
||||
AZStd::map<AZ::u64, uint32>& SharedHelperData::GetEntryStateToStateMachineTable(MCore::Array<SharedData*>* sharedData)
|
||||
{
|
||||
// Find the helper data
|
||||
SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID);
|
||||
SharedHelperData* helperData = static_cast<SharedHelperData*>(data);
|
||||
return helperData->m_entryNodeIndexToStateMachineIdLookupTable;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// constructor
|
||||
@@ -1999,7 +1927,6 @@ namespace EMotionFX
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
bool ChunkProcessorActorAttachmentNodes::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
const MCore::Endian::EEndianType endianType = importParams.mEndianType;
|
||||
@@ -2055,866 +1982,6 @@ namespace EMotionFX
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// animGraph state transitions
|
||||
bool ChunkProcessorAnimGraphStateTransitions::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
// read the number of transitions to follow
|
||||
uint32 numTransitions;
|
||||
file->Read(&numTransitions, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&numTransitions, importParams.mEndianType);
|
||||
|
||||
// read the state machine index
|
||||
uint32 stateMachineIndex;
|
||||
file->Read(&stateMachineIndex, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&stateMachineIndex, importParams.mEndianType);
|
||||
|
||||
// get the loaded anim graph nodes
|
||||
MCore::Array<AnimGraphNode*>& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData);
|
||||
if (stateMachineIndex >= blendNodes.GetLength())
|
||||
{
|
||||
if (GetLogging())
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "State machine refers to invalid blend node, state machine index: %d, amount of blend node: %d", stateMachineIndex, blendNodes.GetLength());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
AZ_Assert(azrtti_typeid(blendNodes[stateMachineIndex]) == azrtti_typeid<AnimGraphStateMachine>(), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateMachine. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex]));
|
||||
AnimGraphStateMachine* stateMachine = static_cast<AnimGraphStateMachine*>(blendNodes[stateMachineIndex]);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Num transitions for state machine '%s' = %d", blendNodes[stateMachineIndex]->GetName(), numTransitions);
|
||||
}
|
||||
|
||||
stateMachine->ReserveTransitions(numTransitions);
|
||||
|
||||
// read the transitions
|
||||
FileFormat::AnimGraph_StateTransition transition;
|
||||
for (uint32 i = 0; i < numTransitions; ++i)
|
||||
{
|
||||
// read the transition
|
||||
file->Read(&transition, sizeof(FileFormat::AnimGraph_StateTransition));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&transition.mSourceNode, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&transition.mDestNode, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&transition.mNumConditions, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetX, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetY, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetX, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetY, importParams.mEndianType);
|
||||
|
||||
//----------------------------------------------
|
||||
// read the node header
|
||||
FileFormat::AnimGraph_NodeHeader nodeHeader;
|
||||
file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- State Transition Node:");
|
||||
MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID);
|
||||
MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion);
|
||||
MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes);
|
||||
MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes);
|
||||
MCore::LogDetailedInfo(" + Num conditions = %d", transition.mNumConditions);
|
||||
MCore::LogDetailedInfo(" + Source node = %d", transition.mSourceNode);
|
||||
MCore::LogDetailedInfo(" + Dest node = %d", transition.mDestNode);
|
||||
}
|
||||
|
||||
// create the transition object
|
||||
AnimGraphStateTransition* emfxTransition = nullptr;
|
||||
if (GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID) == azrtti_typeid<AnimGraphStateTransition>())
|
||||
{
|
||||
emfxTransition = aznew AnimGraphStateTransition();
|
||||
}
|
||||
|
||||
if (emfxTransition)
|
||||
{
|
||||
if (transition.mDestNode >= blendNodes.GetLength())
|
||||
{
|
||||
if (GetLogging())
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "State machine transition refers to invalid destination blend node, transition index %d, blend node: %d", i, transition.mDestNode);
|
||||
}
|
||||
delete emfxTransition;
|
||||
emfxTransition = nullptr;
|
||||
}
|
||||
// A source node index of MCORE_INVALIDINDEX32 indicates that the transition is a wildcard transition. Don't go into error state in this case.
|
||||
else if (transition.mSourceNode != MCORE_INVALIDINDEX32 && transition.mSourceNode >= blendNodes.GetLength())
|
||||
{
|
||||
if (GetLogging())
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "State machine transition refers to invalid source blend node, transition index %d, blend node: %d", i, transition.mSourceNode);
|
||||
}
|
||||
delete emfxTransition;
|
||||
emfxTransition = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimGraphNode* targetNode = blendNodes[transition.mDestNode];
|
||||
if (targetNode == nullptr)
|
||||
{
|
||||
delete emfxTransition;
|
||||
emfxTransition = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(azrtti_istypeof<AnimGraphStateTransition>(emfxTransition), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateTransition. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex]));
|
||||
|
||||
// Now apply the transition settings
|
||||
// Check if we are dealing with a wildcard transition
|
||||
if (transition.mSourceNode == MCORE_INVALIDINDEX32)
|
||||
{
|
||||
emfxTransition->SetSourceNode(nullptr);
|
||||
emfxTransition->SetIsWildcardTransition(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the source node
|
||||
emfxTransition->SetSourceNode(blendNodes[transition.mSourceNode]);
|
||||
}
|
||||
|
||||
// set the destination node
|
||||
emfxTransition->SetTargetNode(targetNode);
|
||||
|
||||
emfxTransition->SetVisualOffsets(transition.mStartOffsetX, transition.mStartOffsetY, transition.mEndOffsetX, transition.mEndOffsetY);
|
||||
|
||||
// now read the attributes
|
||||
if (!LegacyAnimGraphNodeParser::ParseLegacyAttributes<AnimGraphStateTransition>(file, nodeHeader.mNumAttributes, importParams.mEndianType, importParams, *emfxTransition))
|
||||
{
|
||||
delete emfxTransition;
|
||||
emfxTransition = nullptr;
|
||||
AZ_Error("EMotionFX", false, "Unable to parse state transition");
|
||||
return false;
|
||||
}
|
||||
// add the transition to the state machine
|
||||
stateMachine->AddTransition(emfxTransition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (emfxTransition)
|
||||
{
|
||||
// iterate through all conditions
|
||||
for (uint32 c = 0; c < transition.mNumConditions; ++c)
|
||||
{
|
||||
// read the condition node header
|
||||
FileFormat::AnimGraph_NodeHeader conditionHeader;
|
||||
file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo(" - Transition Condition:");
|
||||
MCore::LogDetailedInfo(" + Type = %d", conditionHeader.mTypeID);
|
||||
MCore::LogDetailedInfo(" + Version = %d", conditionHeader.mVersion);
|
||||
MCore::LogDetailedInfo(" + Num data bytes = %d", conditionHeader.mNumCustomDataBytes);
|
||||
MCore::LogDetailedInfo(" + Num attributes = %d", conditionHeader.mNumAttributes);
|
||||
}
|
||||
|
||||
AnimGraphTransitionCondition* emfxCondition = nullptr;
|
||||
if (!LegacyAnimGraphNodeParser::ParseTransitionConditionChunk(file, importParams, conditionHeader, emfxCondition))
|
||||
{
|
||||
AZ_Error("EMotionFX", false, "Unable to parse Transition condition of type %u in legacy file", azrtti_typeid(emfxCondition));
|
||||
delete emfxCondition;
|
||||
emfxCondition = nullptr;
|
||||
return false;
|
||||
}
|
||||
// add the condition to the transition
|
||||
emfxTransition->AddCondition(emfxCondition);
|
||||
}
|
||||
|
||||
//emfxTransition->Init( animGraph );
|
||||
}
|
||||
// something went wrong with creating the transition
|
||||
else
|
||||
{
|
||||
MCore::LogWarning("Cannot load and instantiate state transition. State transition from %d to %d will be skipped.", transition.mSourceNode, transition.mDestNode);
|
||||
|
||||
// skip reading the attributes
|
||||
if (!ForwardAttributes(file, importParams.mEndianType, nodeHeader.mNumAttributes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip reading the node custom data
|
||||
if (file->Forward(nodeHeader.mNumCustomDataBytes) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// iterate through all conditions and skip them as well
|
||||
for (uint32 c = 0; c < transition.mNumConditions; ++c)
|
||||
{
|
||||
// read the condition node header
|
||||
FileFormat::AnimGraph_NodeHeader conditionHeader;
|
||||
file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType);
|
||||
|
||||
// skip reading the attributes
|
||||
if (!ForwardAttributes(file, importParams.mEndianType, conditionHeader.mNumAttributes))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip reading the node custom data
|
||||
if (file->Forward(conditionHeader.mNumCustomDataBytes) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// animGraph state transitions
|
||||
bool ChunkProcessorAnimGraphAdditionalInfo::Process(MCore::File* file, Importer::ImportParameters& /*importParams*/)
|
||||
{
|
||||
return file->Forward(sizeof(FileFormat::AnimGraph_AdditionalInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// animGraph node connections
|
||||
bool ChunkProcessorAnimGraphNodeConnections::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
// read the number of transitions to follow
|
||||
uint32 numConnections;
|
||||
file->Read(&numConnections, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&numConnections, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Num node connections = %d", numConnections);
|
||||
}
|
||||
|
||||
// get the array of currently loaded nodes
|
||||
MCore::Array<AnimGraphNode*>& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData);
|
||||
|
||||
// read the connections
|
||||
FileFormat::AnimGraph_NodeConnection connection;
|
||||
for (uint32 i = 0; i < numConnections; ++i)
|
||||
{
|
||||
// read the transition
|
||||
file->Read(&connection, sizeof(FileFormat::AnimGraph_NodeConnection));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&connection.mSourceNode, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&connection.mTargetNode, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt16(&connection.mSourceNodePort, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt16(&connection.mTargetNodePort, importParams.mEndianType);
|
||||
|
||||
// log details
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo(" + Connection #%d = From node %d (port id %d) into node %d (port id %d)", i, connection.mSourceNode, connection.mSourceNodePort, connection.mTargetNode, connection.mTargetNodePort);
|
||||
}
|
||||
|
||||
// get the source and the target node and check if they are valid
|
||||
AnimGraphNode* sourceNode = blendNodes[connection.mSourceNode];
|
||||
AnimGraphNode* targetNode = blendNodes[connection.mTargetNode];
|
||||
if (sourceNode == nullptr || targetNode == nullptr)
|
||||
{
|
||||
MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target node is invalid! (sourcePortID=%d targetPortID=%d sourceNode=%d targetNode=%d)", connection.mSourceNodePort, connection.mTargetNodePort, connection.mSourceNode, connection.mTargetNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
// create the connection
|
||||
const uint32 sourcePort = blendNodes[connection.mSourceNode]->FindOutputPortByID(connection.mSourceNodePort);
|
||||
const uint32 targetPort = blendNodes[connection.mTargetNode]->FindInputPortByID(connection.mTargetNodePort);
|
||||
if (sourcePort != MCORE_INVALIDINDEX32 && targetPort != MCORE_INVALIDINDEX32)
|
||||
{
|
||||
blendNodes[connection.mTargetNode]->AddConnection(blendNodes[connection.mSourceNode], static_cast<uint16>(sourcePort), static_cast<uint16>(targetPort));
|
||||
}
|
||||
else
|
||||
{
|
||||
MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target port doesn't exist! (sourcePortID=%d targetPortID=%d sourceNode='%s' targetNode=%s')", connection.mSourceNodePort, connection.mTargetNodePort, blendNodes[connection.mSourceNode]->GetName(), blendNodes[connection.mTargetNode]->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// animGraph node
|
||||
bool ChunkProcessorAnimGraphNode::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
AnimGraph* animGraph = importParams.mAnimGraph;
|
||||
MCORE_ASSERT(animGraph);
|
||||
|
||||
// read the node header
|
||||
FileFormat::AnimGraph_NodeHeader nodeHeader;
|
||||
file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType);
|
||||
MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType);
|
||||
|
||||
const char* nodeName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Blend Node:");
|
||||
MCore::LogDetailedInfo(" + Name = %s", nodeName);
|
||||
MCore::LogDetailedInfo(" + Parent index = %d", nodeHeader.mParentIndex);
|
||||
MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID);
|
||||
MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion);
|
||||
MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes);
|
||||
MCore::LogDetailedInfo(" + Num child nodes = %d", nodeHeader.mNumChildNodes);
|
||||
MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes);
|
||||
MCore::LogDetailedInfo(" + Visualize Color = %d, %d, %d", MCore::ExtractRed(nodeHeader.mVisualizeColor), MCore::ExtractGreen(nodeHeader.mVisualizeColor), MCore::ExtractBlue(nodeHeader.mVisualizeColor));
|
||||
MCore::LogDetailedInfo(" + Visual pos = (%d, %d)", nodeHeader.mVisualPosX, nodeHeader.mVisualPosY);
|
||||
MCore::LogDetailedInfo(" + Collapsed = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_COLLAPSED) ? "Yes" : "No");
|
||||
MCore::LogDetailedInfo(" + Visualized = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VISUALIZED) ? "Yes" : "No");
|
||||
MCore::LogDetailedInfo(" + Disabled = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_DISABLED) ? "Yes" : "No");
|
||||
MCore::LogDetailedInfo(" + Virtual FinalOut= %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT) ? "Yes" : "No");
|
||||
}
|
||||
|
||||
AnimGraphNode* node = nullptr;
|
||||
if (!LegacyAnimGraphNodeParser::ParseAnimGraphNodeChunk(file
|
||||
, importParams
|
||||
, nodeName
|
||||
, nodeHeader
|
||||
, node))
|
||||
{
|
||||
if (importParams.mAnimGraph->GetRootStateMachine() == node)
|
||||
{
|
||||
importParams.mAnimGraph->SetRootStateMachine(nullptr);
|
||||
}
|
||||
|
||||
if (node)
|
||||
{
|
||||
AnimGraphNode* parentNode = node->GetParentNode();
|
||||
if (parentNode)
|
||||
{
|
||||
parentNode->RemoveChildNodeByPointer(node, false);
|
||||
}
|
||||
}
|
||||
|
||||
delete node;
|
||||
node = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
EMotionFX::GetEventManager().OnCreatedNode(animGraph, node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// animGraph parameters
|
||||
bool ChunkProcessorAnimGraphParameters::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
AnimGraph* animGraph = importParams.mAnimGraph;
|
||||
MCORE_ASSERT(animGraph);
|
||||
|
||||
// read the number of parameters
|
||||
uint32 numParams;
|
||||
file->Read(&numParams, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&numParams, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Num parameters = %d", numParams);
|
||||
}
|
||||
|
||||
// read all parameters
|
||||
for (uint32 p = 0; p < numParams; ++p)
|
||||
{
|
||||
// read the parameter info header
|
||||
FileFormat::AnimGraph_ParameterInfo paramInfo;
|
||||
file->Read(¶mInfo, sizeof(FileFormat::AnimGraph_ParameterInfo));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(¶mInfo.mNumComboValues, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(¶mInfo.mInterfaceType, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(¶mInfo.mAttributeType, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt16(¶mInfo.mFlags, importParams.mEndianType);
|
||||
|
||||
// check the attribute type
|
||||
const uint32 attribType = paramInfo.mAttributeType;
|
||||
if (attribType == 0)
|
||||
{
|
||||
MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to convert interface type %d to an attribute type.", attribType);
|
||||
return false;
|
||||
}
|
||||
|
||||
const AZ::TypeId parameterTypeId = EMotionFX::FileFormat::GetParameterTypeIdForInterfaceType(paramInfo.mInterfaceType);
|
||||
const AZStd::string name = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
AZStd::unique_ptr<EMotionFX::Parameter> newParam(EMotionFX::ParameterFactory::Create(parameterTypeId));
|
||||
AZ_Assert(azrtti_istypeof<EMotionFX::ValueParameter>(newParam.get()), "Expected a value parameter");
|
||||
|
||||
if (!newParam)
|
||||
{
|
||||
MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to create parameter: '%s'.", name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the strings
|
||||
newParam->SetName(name);
|
||||
SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); // We dont use internal name anymore
|
||||
newParam->SetDescription(SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType));
|
||||
|
||||
// log the details
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Parameter #%d:", p);
|
||||
MCore::LogDetailedInfo(" + Name = %s", newParam->GetName().c_str());
|
||||
MCore::LogDetailedInfo(" + Description = %s", newParam->GetDescription().c_str());
|
||||
MCore::LogDetailedInfo(" + type = %s", newParam->RTTI_GetTypeName());
|
||||
MCore::LogDetailedInfo(" + Attribute type = %d", paramInfo.mAttributeType);
|
||||
MCore::LogDetailedInfo(" + Has MinMax = %d", paramInfo.mHasMinMax);
|
||||
MCore::LogDetailedInfo(" + Flags = %d", paramInfo.mFlags);
|
||||
}
|
||||
|
||||
MCore::Attribute* attr(MCore::GetAttributeFactory().CreateAttributeByType(attribType));
|
||||
EMotionFX::ValueParameter* valueParameter = static_cast<EMotionFX::ValueParameter*>(newParam.get());
|
||||
|
||||
// create the min, max and default value attributes
|
||||
if (paramInfo.mHasMinMax == 1)
|
||||
{
|
||||
// min value
|
||||
attr->Read(file, importParams.mEndianType);
|
||||
valueParameter->SetMinValueFromAttribute(attr);
|
||||
|
||||
// max value
|
||||
attr->Read(file, importParams.mEndianType);
|
||||
valueParameter->SetMaxValueFromAttribute(attr);
|
||||
}
|
||||
|
||||
// default value
|
||||
attr->Read(file, importParams.mEndianType);
|
||||
valueParameter->SetDefaultValueFromAttribute(attr);
|
||||
delete attr;
|
||||
|
||||
// Parameters were previously stored in "AttributeSettings". The calss supported
|
||||
// multiple values, however, the UI did not, so this ended up not being used.
|
||||
// Support for multiple values in parameters is possible, however we dont need it now.
|
||||
// Leaving this code as reference
|
||||
for (uint32 i = 0; i < paramInfo.mNumComboValues; ++i)
|
||||
{
|
||||
SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
}
|
||||
|
||||
if (!animGraph->AddParameter(newParam.get()))
|
||||
{
|
||||
MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to add parameter: '%s'.", name.c_str());
|
||||
return false;
|
||||
}
|
||||
newParam.release(); // ownership moved to animGraph
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// animGraph node groups
|
||||
bool ChunkProcessorAnimGraphNodeGroups::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
AnimGraph* animGraph = importParams.mAnimGraph;
|
||||
MCORE_ASSERT(animGraph);
|
||||
|
||||
// read the number of node groups
|
||||
uint32 numNodeGroups;
|
||||
file->Read(&numNodeGroups, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&numNodeGroups, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Num Node Groups = %d", numNodeGroups);
|
||||
}
|
||||
|
||||
// read all node groups
|
||||
for (uint32 g = 0; g < numNodeGroups; ++g)
|
||||
{
|
||||
// read the node group header
|
||||
FileFormat::AnimGraph_NodeGroup nodeGroupChunk;
|
||||
file->Read(&nodeGroupChunk, sizeof(FileFormat::AnimGraph_NodeGroup));
|
||||
|
||||
MCore::RGBAColor emfxColor(nodeGroupChunk.mColor.mR, nodeGroupChunk.mColor.mG, nodeGroupChunk.mColor.mB, nodeGroupChunk.mColor.mA);
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeGroupChunk.mNumNodes, importParams.mEndianType);
|
||||
MCore::Endian::ConvertRGBAColor(&emfxColor, importParams.mEndianType);
|
||||
|
||||
const AZ::Color color128 = MCore::EmfxColorToAzColor(emfxColor);
|
||||
const AZ::u32 color32 = color128.ToU32();
|
||||
|
||||
const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
const uint32 numNodes = nodeGroupChunk.mNumNodes;
|
||||
|
||||
// create and fill the new node group
|
||||
AnimGraphNodeGroup* nodeGroup = aznew AnimGraphNodeGroup(groupName);
|
||||
animGraph->AddNodeGroup(nodeGroup);
|
||||
nodeGroup->SetIsVisible(nodeGroupChunk.mIsVisible != 0);
|
||||
nodeGroup->SetColor(color32);
|
||||
|
||||
// set the nodes of the node group
|
||||
MCore::Array<AnimGraphNode*>& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData);
|
||||
nodeGroup->SetNumNodes(numNodes);
|
||||
for (uint32 i = 0; i < numNodes; ++i)
|
||||
{
|
||||
// read the node index of the current node inside the group
|
||||
uint32 nodeNr;
|
||||
file->Read(&nodeNr, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&nodeNr, importParams.mEndianType);
|
||||
|
||||
MCORE_ASSERT(nodeNr != MCORE_INVALIDINDEX32);
|
||||
|
||||
// set the id of the given node to the group
|
||||
if (nodeNr != MCORE_INVALIDINDEX32 && blendNodes[nodeNr])
|
||||
{
|
||||
nodeGroup->SetNode(i, blendNodes[nodeNr]->GetId());
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeGroup->SetNode(i, AnimGraphNodeId::InvalidId);
|
||||
}
|
||||
}
|
||||
|
||||
// log the details
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Node Group #%d:", g);
|
||||
MCore::LogDetailedInfo(" + Name = %s", nodeGroup->GetName());
|
||||
MCore::LogDetailedInfo(" + Color = (%.2f, %.2f, %.2f, %.2f)", static_cast<float>(color128.GetR()), static_cast<float>(color128.GetG()), static_cast<float>(color128.GetB()), static_cast<float>(color128.GetA()));
|
||||
MCore::LogDetailedInfo(" + Num Nodes = %i", nodeGroup->GetNumNodes());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// animGraph group parameters
|
||||
bool ChunkProcessorAnimGraphGroupParameters::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
AnimGraph* animGraph = importParams.mAnimGraph;
|
||||
MCORE_ASSERT(animGraph);
|
||||
|
||||
// read the number of group parameters
|
||||
uint32 numGroupParameters;
|
||||
file->Read(&numGroupParameters, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(&numGroupParameters, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Num group parameters = %d", numGroupParameters);
|
||||
}
|
||||
|
||||
// Group parameters is going to re-shuffle the value parameter indices, therefore we
|
||||
// need to update the connections downstream of parameter nodes.
|
||||
EMotionFX::ValueParameterVector valueParametersBeforeChange = animGraph->RecursivelyGetValueParameters();
|
||||
|
||||
// Since relocating a parameter to another parent changes its index, we are going to
|
||||
// compute all the relationships leaving the value parameters at the root, then relocate
|
||||
// them.
|
||||
AZStd::vector<AZStd::pair<const EMotionFX::GroupParameter*, EMotionFX::ParameterVector> > parametersByGroup;
|
||||
|
||||
// read all group parameters
|
||||
for (uint32 g = 0; g < numGroupParameters; ++g)
|
||||
{
|
||||
// read the group parameter header
|
||||
FileFormat::AnimGraph_GroupParameter groupChunk;
|
||||
file->Read(&groupChunk, sizeof(FileFormat::AnimGraph_GroupParameter));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&groupChunk.mNumParameters, importParams.mEndianType);
|
||||
|
||||
const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
const uint32 numParameters = groupChunk.mNumParameters;
|
||||
|
||||
// create and fill the new group parameter
|
||||
AZStd::unique_ptr<EMotionFX::Parameter> parameter(EMotionFX::ParameterFactory::Create(azrtti_typeid<EMotionFX::GroupParameter>()));
|
||||
parameter->SetName(groupName);
|
||||
|
||||
// Previously collapsed/expanded state in group parameters was stored in the animgraph file. However, that
|
||||
// would require to check out the animgraph file if you expand/collapse a group. Because this change was not
|
||||
// done through commands, the dirty state was not properly restored.
|
||||
// Collapsing state should be more of a setting per-user than something saved in the animgraph
|
||||
//groupParameter->SetIsCollapsed(groupChunk.mCollapsed != 0);
|
||||
|
||||
if (!animGraph->AddParameter(parameter.get()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const EMotionFX::GroupParameter* groupParameter = static_cast<EMotionFX::GroupParameter*>(parameter.release());
|
||||
|
||||
parametersByGroup.emplace_back(groupParameter, EMotionFX::ParameterVector());
|
||||
AZStd::vector<EMotionFX::Parameter*>& parametersInGroup = parametersByGroup.back().second;
|
||||
|
||||
// set the parameters of the group parameter
|
||||
for (uint32 i = 0; i < numParameters; ++i)
|
||||
{
|
||||
// read the parameter index
|
||||
uint32 parameterIndex;
|
||||
file->Read(¶meterIndex, sizeof(uint32));
|
||||
MCore::Endian::ConvertUnsignedInt32(¶meterIndex, importParams.mEndianType);
|
||||
|
||||
MCORE_ASSERT(parameterIndex != MCORE_INVALIDINDEX32);
|
||||
if (parameterIndex != MCORE_INVALIDINDEX32)
|
||||
{
|
||||
const EMotionFX::Parameter* childParameter = animGraph->FindValueParameter(parameterIndex);
|
||||
parametersInGroup.emplace_back(const_cast<EMotionFX::Parameter*>(childParameter));
|
||||
}
|
||||
}
|
||||
|
||||
// log the details
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Group parameter #%d:", g);
|
||||
MCore::LogDetailedInfo(" + Name = %s", groupParameter->GetName().c_str());
|
||||
MCore::LogDetailedInfo(" + Num Parameters = %i", groupParameter->GetNumParameters());
|
||||
}
|
||||
}
|
||||
|
||||
// Now move the parameters to their groups
|
||||
for (const AZStd::pair<const EMotionFX::GroupParameter*, EMotionFX::ParameterVector>& groupAndParameters : parametersByGroup)
|
||||
{
|
||||
const EMotionFX::GroupParameter* groupParameter = groupAndParameters.first;
|
||||
for (EMotionFX::Parameter* parameter : groupAndParameters.second)
|
||||
{
|
||||
animGraph->TakeParameterFromParent(parameter);
|
||||
animGraph->AddParameter(const_cast<EMotionFX::Parameter*>(parameter), groupParameter);
|
||||
}
|
||||
}
|
||||
|
||||
const EMotionFX::ValueParameterVector valueParametersAfterChange = animGraph->RecursivelyGetValueParameters();
|
||||
|
||||
AZStd::vector<EMotionFX::AnimGraphObject*> affectedObjects;
|
||||
animGraph->RecursiveCollectObjectsOfType(azrtti_typeid<EMotionFX::ObjectAffectedByParameterChanges>(), affectedObjects);
|
||||
|
||||
for (EMotionFX::AnimGraphObject* affectedObject : affectedObjects)
|
||||
{
|
||||
EMotionFX::ObjectAffectedByParameterChanges* affectedObjectByParameterChanges = azdynamic_cast<EMotionFX::ObjectAffectedByParameterChanges*>(affectedObject);
|
||||
affectedObjectByParameterChanges->ParameterOrderChanged(valueParametersBeforeChange, valueParametersAfterChange);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// animGraph game controller settings
|
||||
bool ChunkProcessorAnimGraphGameControllerSettings::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
AnimGraph* animGraph = importParams.mAnimGraph;
|
||||
MCORE_ASSERT(animGraph);
|
||||
|
||||
// get the game controller settings for the anim graph and clear it
|
||||
AnimGraphGameControllerSettings& gameControllerSettings = animGraph->GetGameControllerSettings();
|
||||
gameControllerSettings.Clear();
|
||||
|
||||
// read the number of presets and the active preset index
|
||||
uint32 activePresetIndex, numPresets;
|
||||
file->Read(&activePresetIndex, sizeof(uint32));
|
||||
file->Read(&numPresets, sizeof(uint32));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&activePresetIndex, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&numPresets, importParams.mEndianType);
|
||||
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Game Controller Settings (NumPresets=%d, ActivePreset=%d)", numPresets, activePresetIndex);
|
||||
}
|
||||
|
||||
// preallocate memory for the presets
|
||||
gameControllerSettings.SetNumPresets(numPresets);
|
||||
|
||||
// read all presets
|
||||
for (uint32 p = 0; p < numPresets; ++p)
|
||||
{
|
||||
// read the preset chunk
|
||||
FileFormat::AnimGraph_GameControllerPreset presetChunk;
|
||||
file->Read(&presetChunk, sizeof(FileFormat::AnimGraph_GameControllerPreset));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumParameterInfos, importParams.mEndianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumButtonInfos, importParams.mEndianType);
|
||||
|
||||
// read the preset name and get the number of parameter and button infos
|
||||
const char* presetName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
const uint32 numParamInfos = presetChunk.mNumParameterInfos;
|
||||
const uint32 numButtonInfos = presetChunk.mNumButtonInfos;
|
||||
|
||||
// create and fill the new preset
|
||||
AnimGraphGameControllerSettings::Preset* preset = aznew AnimGraphGameControllerSettings::Preset(presetName);
|
||||
gameControllerSettings.SetPreset(p, preset);
|
||||
|
||||
// read the parameter infos
|
||||
preset->SetNumParamInfos(numParamInfos);
|
||||
for (i = 0; i < numParamInfos; ++i)
|
||||
{
|
||||
// read the parameter info chunk
|
||||
FileFormat::AnimGraph_GameControllerParameterInfo paramInfoChunk;
|
||||
file->Read(¶mInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerParameterInfo));
|
||||
|
||||
// read the parameter name
|
||||
const char* parameterName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
|
||||
// construct and fill the parameter info
|
||||
AnimGraphGameControllerSettings::ParameterInfo* parameterInfo = aznew AnimGraphGameControllerSettings::ParameterInfo(parameterName);
|
||||
parameterInfo->m_axis = paramInfoChunk.mAxis;
|
||||
parameterInfo->m_invert = (paramInfoChunk.mInvert != 0);
|
||||
parameterInfo->m_mode = (AnimGraphGameControllerSettings::ParameterMode)paramInfoChunk.mMode;
|
||||
|
||||
preset->SetParamInfo(i, parameterInfo);
|
||||
}
|
||||
|
||||
// read the button infos
|
||||
preset->SetNumButtonInfos(numButtonInfos);
|
||||
for (i = 0; i < numButtonInfos; ++i)
|
||||
{
|
||||
// read the button info chunk
|
||||
FileFormat::AnimGraph_GameControllerButtonInfo buttonInfoChunk;
|
||||
file->Read(&buttonInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerButtonInfo));
|
||||
|
||||
// read the button string
|
||||
const char* buttonString = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType);
|
||||
|
||||
// construct and fill the button info
|
||||
AnimGraphGameControllerSettings::ButtonInfo* buttonInfo = aznew AnimGraphGameControllerSettings::ButtonInfo(buttonInfoChunk.mButtonIndex);
|
||||
buttonInfo->m_mode = (AnimGraphGameControllerSettings::ButtonMode)buttonInfoChunk.mMode;
|
||||
buttonInfo->m_string = buttonString;
|
||||
|
||||
preset->SetButtonInfo(i, buttonInfo);
|
||||
}
|
||||
|
||||
// log the details
|
||||
if (GetLogging())
|
||||
{
|
||||
MCore::LogDetailedInfo("- Preset '%s':", preset->GetName());
|
||||
MCore::LogDetailedInfo(" + Num Param Infos = %d", preset->GetNumParamInfos());
|
||||
MCore::LogDetailedInfo(" + Num Button Infos = %d", preset->GetNumButtonInfos());
|
||||
}
|
||||
}
|
||||
|
||||
// set the active preset
|
||||
if (activePresetIndex != MCORE_INVALIDINDEX32)
|
||||
{
|
||||
AnimGraphGameControllerSettings::Preset* activePreset = gameControllerSettings.GetPreset(activePresetIndex);
|
||||
gameControllerSettings.SetActivePreset(activePreset);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// MotionSet
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// all submotions in one chunk
|
||||
bool ChunkProcessorMotionSet::Process(MCore::File* file, Importer::ImportParameters& importParams)
|
||||
{
|
||||
const MCore::Endian::EEndianType endianType = importParams.mEndianType;
|
||||
|
||||
FileFormat::MotionSetsChunk motionSetsChunk;
|
||||
file->Read(&motionSetsChunk, sizeof(FileFormat::MotionSetsChunk));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&motionSetsChunk.mNumSets, endianType);
|
||||
|
||||
// get the number of motion sets and iterate through them
|
||||
const uint32 numMotionSets = motionSetsChunk.mNumSets;
|
||||
for (uint32 i = 0; i < numMotionSets; ++i)
|
||||
{
|
||||
FileFormat::MotionSetChunk motionSetChunk;
|
||||
file->Read(&motionSetChunk, sizeof(FileFormat::MotionSetChunk));
|
||||
|
||||
// convert endian
|
||||
MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumChildSets, endianType);
|
||||
MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumMotionEntries, endianType);
|
||||
|
||||
// get the parent set
|
||||
const char* parentSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType);
|
||||
GetMotionManager().Lock();
|
||||
MotionSet* parentSet = GetMotionManager().FindMotionSetByName(parentSetName, importParams.m_isOwnedByRuntime);
|
||||
GetMotionManager().Unlock();
|
||||
|
||||
// read the motion set name and create our new motion set
|
||||
const char* motionSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType);
|
||||
MotionSet* motionSet = aznew MotionSet(motionSetName, parentSet);
|
||||
motionSet->SetIsOwnedByRuntime(importParams.m_isOwnedByRuntime);
|
||||
|
||||
// set the root motion set to the importer params motion set, this will be returned by the Importer::LoadMotionSet() function
|
||||
if (parentSet == nullptr)
|
||||
{
|
||||
assert(importParams.mMotionSet == nullptr);
|
||||
importParams.mMotionSet = motionSet;
|
||||
}
|
||||
|
||||
// read the filename and set it
|
||||
/*const char* motionSetFileName = */ SharedHelperData::ReadString(file, importParams.mSharedData, endianType);
|
||||
//motionSet->SetFileName( motionSetFileName );
|
||||
|
||||
// in case this is not a root motion set add the new motion set as child set to the parent set
|
||||
if (parentSet)
|
||||
{
|
||||
parentSet->AddChildSet(motionSet);
|
||||
}
|
||||
|
||||
// Read all motion entries.
|
||||
const uint32 numMotionEntries = motionSetChunk.mNumMotionEntries;
|
||||
motionSet->ReserveMotionEntries(numMotionEntries);
|
||||
AZStd::string nativeMotionFileName;
|
||||
for (uint32 j = 0; j < numMotionEntries; ++j)
|
||||
{
|
||||
// read the motion entry
|
||||
const char* motionFileName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType);
|
||||
nativeMotionFileName = motionFileName;
|
||||
|
||||
// read the string id and set it
|
||||
const char* motionStringID = SharedHelperData::ReadString(file, importParams.mSharedData, endianType);
|
||||
|
||||
// add the motion entry to the motion set
|
||||
MotionSet::MotionEntry* motionEntry = aznew MotionSet::MotionEntry(nativeMotionFileName.c_str(), motionStringID);
|
||||
motionSet->AddMotionEntry(motionEntry);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
// NodeMap
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "SharedFileFormatStructs.h"
|
||||
#include "ActorFileFormat.h"
|
||||
#include "MotionFileFormat.h"
|
||||
#include "AnimGraphFileFormat.h"
|
||||
#include "MotionSetFileFormat.h"
|
||||
#include "NodeMapFileFormat.h"
|
||||
#include "Importer.h"
|
||||
#include <AzCore/std/containers/map.h>
|
||||
@@ -32,7 +30,6 @@ namespace EMotionFX
|
||||
class Importer;
|
||||
class AnimGraphNode;
|
||||
|
||||
|
||||
/**
|
||||
* Shared importer data class.
|
||||
* Chunks can load data, which might be shared between other chunks during import.
|
||||
@@ -57,20 +54,11 @@ namespace EMotionFX
|
||||
virtual void Reset() {}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
SharedData()
|
||||
: BaseObject() {}
|
||||
|
||||
/**
|
||||
* The destructor.
|
||||
*/
|
||||
virtual ~SharedData() { Reset(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper class for reading strings from files and file information storage.
|
||||
*/
|
||||
@@ -108,34 +96,12 @@ namespace EMotionFX
|
||||
*/
|
||||
static const char* ReadString(MCore::Stream* file, MCore::Array<SharedData*>* sharedData, MCore::Endian::EEndianType endianType);
|
||||
|
||||
/**
|
||||
* Get the array of currently loaded anim graph nodes.
|
||||
* @param sharedData The array which holds the shared data objects.
|
||||
* @result The array of currently loaded anim graph nodes.
|
||||
*/
|
||||
static MCore::Array<AnimGraphNode*>& GetBlendNodes(MCore::Array<SharedData*>* sharedData);
|
||||
|
||||
/**
|
||||
* Get the table to look up a state machine that needs an entry state as they are created.
|
||||
* @param sharedData The array which holds the shared data objects.
|
||||
* @result The map whose keys are the indices of entry states and the values are the IDs of the state machines that need those as entry states.
|
||||
*/
|
||||
static AZStd::map<AZ::u64, uint32>& GetEntryStateToStateMachineTable(MCore::Array<SharedData*>* sharedData);
|
||||
|
||||
/**
|
||||
* Checks if the strings in the file are encoded using unicode or multi-byte based on the exporter date.
|
||||
* The first official EMotion FX version to use unicode was compiled on 26th November 2012.
|
||||
*/
|
||||
static bool GetIsUnicodeFile(const char* dateString, MCore::Array<SharedData*>* sharedData);
|
||||
|
||||
public:
|
||||
uint32 mFileHighVersion; /**< The high file version. For example 3 in case of v3.10. */
|
||||
uint32 mFileLowVersion; /**< The low file version. For example 10 in case of v3.10. */
|
||||
uint32 mStringStorageSize; /**< The size of the string buffer. */
|
||||
bool mIsUnicodeFile; /**< True in case strings in the file are saved using unicode character set, false in case they are saved using multi-byte. */
|
||||
char* mStringStorage; /**< The shared string buffer. */
|
||||
MCore::Array<AnimGraphNode*> mBlendNodes; /**< Array of read anim graph nodes. */
|
||||
AZStd::map<AZ::u64, uint32> m_entryNodeIndexToStateMachineIdLookupTable;
|
||||
protected:
|
||||
/**
|
||||
* The constructor.
|
||||
@@ -338,22 +304,6 @@ namespace EMotionFX
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionMorphSubMotions, FileFormat::MOTION_CHUNK_MORPHSUBMOTIONS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionData, FileFormat::MOTION_CHUNK_MOTIONDATA, 1)
|
||||
|
||||
// Anim graph file format chunk processors
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphStateTransitions, FileFormat::ANIMGRAPH_CHUNK_STATETRANSITIONS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeConnections, FileFormat::ANIMGRAPH_CHUNK_NODECONNECTIONS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphParameters, FileFormat::ANIMGRAPH_CHUNK_PARAMETERS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeGroups, FileFormat::ANIMGRAPH_CHUNK_NODEGROUPS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGroupParameters, FileFormat::ANIMGRAPH_CHUNK_GROUPPARAMETERS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGameControllerSettings, FileFormat::ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNode, FileFormat::ANIMGRAPH_CHUNK_BLENDNODE, 1)
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphAdditionalInfo, FileFormat::ANIMGRAPH_CHUNK_ADDITIONALINFO, 1)
|
||||
|
||||
// motion set file format chunk processors
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorMotionSet, FileFormat::CHUNK_MOTIONSET, 1)
|
||||
|
||||
// node map file format chunk processors
|
||||
EMFX_CHUNKPROCESSOR(ChunkProcessorNodeMap, FileFormat::CHUNK_NODEMAP, 1)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
} // namespace EMotionFX
|
||||
|
||||
Reference in New Issue
Block a user